自主协议库编译通过

This commit is contained in:
lnk
2026-06-15 15:48:16 +08:00
parent d3579a2aa7
commit 7205cb5cb9
621 changed files with 224958 additions and 48 deletions

889
mmslib/util/cfg_util.c Normal file
View File

@@ -0,0 +1,889 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1991-2006, All Rights Reserved */
/* */
/* MODULE NAME : cfg_util.c */
/* PRODUCT(S) : */
/* */
/* MODULE DESCRIPTION : */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 02/07/06 EJV 18 cfg_special_char_str: added '$'. */
/* 02/20/03 JRB 17 Del PSOS code. */
/* 11/29/01 EJV 16 Del code for old LATT, XENIX, ultrix, RMX86. */
/* Removed call to strcasecmp (sun) */
/* 10/18/01 JRB 15 Add str_util.h (for strcmpi, etc. protos) */
/* 01/19/01 EJV 14 Moved strcmpi,stricmp,strnicmp to str_util.c */
/* 11/07/00 JRB 13 Del QNX from ifdef. It supports stricmp, etc.*/
/* 04/28/00 JRB 12 Lint cleanup */
/* 09/13/99 MDE 11 Added SD_CONST modifiers */
/* 04/14/99 MDE 10 Replaced SYSTEM_SEL with compiler defines */
/* 10/08/98 MDE 09 Migrated to updated SLOG interface */
/* 08/24/98 EJV 08 Added __hpux to str* cmp functions */
/* 08/06/98 JRB 07 Added cfg_get_octet_string function. */
/* 06/15/98 MDE 06 Changes to allow compile under C++ */
/* 05/22/98 EJV 05 added _AIX, sun, and __alpha to */
/* stricmp, strcmpi, strnicmp functions */
/* 04/03/98 RKR 04 added stricmp, strcmpi, strnicmp */
/* 12/22/97 JRB 03 Clean up PSOS code. */
/* 12/04/97 KCR 02 Added cfg_goto_keyword function */
/* 11/05/97 MDE 01 Added VXWORKS support */
/* 04/02/97 DTL 7.00 MMSEASE 7.0 release. See MODL70.DOC for */
/* history. */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#include "mem_chk.h"
#include "cfg_util.h"
#include "cfglog.h"
#include "str_util.h"
#include <ctype.h>
#include "slog.h"
/************************************************************************/
/* #define DEBUG */
/************************************************************************/
/* For debug version, use a static pointer to avoid duplication of */
/* __FILE__ strings. */
#ifdef DEBUG_SISCO
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
#endif
/************************************************************************/
/* Externally visable variables */
ST_CHAR *cfg_line_buf; /* File line read buffer */
ST_INT cfg_curr_line; /* Current line number */
ST_INT cfg_line_offset; /* Offset into cfg_line_buf */
ST_CHAR *cfg_special_char_str;
ST_CHAR *cfg_end_of_rval_str;
ST_BOOLEAN config_stop;
ST_RET config_err;
ST_BOOLEAN config_eof;
ST_UINT cfg_log_mask;
#ifdef DEBUG_SISCO
SD_CONST ST_CHAR *SD_CONST _cfg_err_logstr = "CFG_LOG_ERR";
SD_CONST ST_CHAR *SD_CONST _cfg_flow_logstr = "CFG_LOG_FLOW";
#endif
/************************************************************************/
/* Internal definitions */
#define MAX_STRING_LEN 256
#define LINE_BUF_SIZE 256
ST_INT cfg_max_string_len;
ST_INT cfg_line_buf_size;
ST_INT cfg_max_rval_len;
#define MAX_CONFIG_NEST 10
/* Internal variables */
static ST_CHAR *cfg_string_buf;
static struct cfg_kw_el *curr_table;
static ST_BOOLEAN cfg_need_new_line;
static FILE *config_fptr; /* Configuration file handle */
/* Keyword table stack control */
static ST_INT num_on_stack;
static struct cfg_kw_el **cfg_kw_stack;
/* Internal funtions */
static struct cfg_kw_el *cfg_lookup_keyword (struct cfg_kw_el *, ST_CHAR *);
static ST_RET cfg_get_next_keyword (FILE *);
static ST_CHAR *cfg_get_rval (ST_VOID);
static ST_RET cfg_end_of_rval (ST_CHAR c);
static ST_RET cfg_special_char (ST_CHAR c);
/************************************************************************/
/************************************************************************/
/************************************************************************/
/* cfg_process_file */
/************************************************************************/
ST_RET cfg_process_file (ST_CHAR *fileName, struct cfg_kw_el *root_kw_tbl)
{
ST_RET ret;
if (cfg_special_char_str == NULL)
cfg_special_char_str = ":\\/-_ .{}[]<>@,()$";
if (cfg_end_of_rval_str == NULL)
cfg_end_of_rval_str = "|";
if (cfg_max_string_len == 0)
cfg_max_string_len = MAX_STRING_LEN;
if (cfg_line_buf_size == 0)
cfg_line_buf_size = LINE_BUF_SIZE;
if (cfg_max_rval_len == 0)
cfg_max_rval_len = MAX_RVAL_LEN;
/* Open the configuration file */
if ((config_fptr = fopen (fileName,"r"))==NULL)
{
CFG_LOG_ERR1 ("Config File (%s) Open Error",fileName);
return (SD_FAILURE);
}
CFG_LOG_FLOW1 ("Config File (%s) Opened OK",fileName);
/* If a previous call to the function ended in error there may be some */
/* old keyword table pushed on the stack. The keywords table stack is */
/* initialized to zero to process the current configuration file */
num_on_stack = 0;
/* Allocate required buffers */
cfg_line_buf = (ST_CHAR *) chk_calloc (cfg_line_buf_size,
sizeof(ST_CHAR));
cfg_string_buf = (ST_CHAR *) chk_calloc (cfg_max_string_len+1,
sizeof(ST_CHAR));
cfg_kw_stack = (struct cfg_kw_el **) chk_calloc (MAX_CONFIG_NEST,
sizeof (struct cfg_kw_el *));
/* Start with the ROOT keyword table */
cfg_tbl_push (root_kw_tbl);
/* Process the configuration file */
cfg_need_new_line = SD_TRUE;
cfg_line_offset = 0;
cfg_curr_line = 0;
config_err = SD_FALSE;
config_stop = SD_FALSE;
config_eof = SD_FAILURE;
/* Process keywords while not done and no error is detected */
while ( ( config_stop == SD_FALSE ) && ( config_err == SD_FALSE ) )
{
if ( cfg_get_next_keyword( config_fptr ) )
break;
}
/* All done, see if it went OK */
if ( ( config_stop == SD_TRUE ) && ( config_err == SD_FALSE ) )
{
CFG_LOG_CFLOW0 ("Config File Read OK");
ret = SD_SUCCESS;
}
else
{
CFG_LOG_ERR3 ("Config Error, Line %d, \"%s\", Column %d",
cfg_curr_line, cfg_line_buf, cfg_line_offset);
ret = SD_FAILURE;
}
/* Free allocated buffers */
chk_free (cfg_line_buf);
chk_free (cfg_string_buf);
chk_free (cfg_kw_stack);
/* Close the file so the calling program can reopen it if necessary. */
fclose( config_fptr );
return (ret);
}
/************************************************************************/
/************************************************************************/
/* cfg_get_next_keyword */
/************************************************************************/
/* This function is used to get the next keyword */
static ST_RET cfg_get_next_keyword (FILE *fptr)
{
struct cfg_kw_el *ptr;
ST_INT i;
ST_CHAR c;
/* Look for 'yyy =' string */
while (SD_TRUE) /* While looking for the next word */
{
if (cfg_need_new_line)
{
if ( fgets( cfg_line_buf, cfg_line_buf_size - 1, fptr ) == NULL )
{
CFG_LOG_CFLOW0 ("No More Keywords : End Of File");
/* The following piece of logic exists to allow the state functions to */
/* declare when it is ok for the file to be out of keywords. If a user */
/* state function set 'config_eof == SD_SUCCESS' then config_stop is set */
/* to true when ENDFILE is encountered. */
if ( config_eof == SD_SUCCESS )
{
config_stop = SD_TRUE;
}
return( SD_FAILURE );
}
/* Wack the \n */
for (i = 0; i < cfg_line_buf_size; ++i)
{
if (cfg_line_buf[i] == '\n')
{
cfg_line_buf[i] = 0;
break;
}
}
cfg_line_offset = 0; /* Offset is 0 for new line */
++cfg_curr_line;
if (cfg_line_buf[0] == '#')
continue; /* Discard comment lines */
cfg_need_new_line = SD_FALSE; /* Got a new line */
}
/* We now have a line to work on, with cfg_line_offset the 1st char */
/* Extract the keyword from the string (alpha numeric characters) */
/* '=' means end of rval */
/* 0 is end of line */
i = 0;
c = cfg_line_buf[cfg_line_offset++];
while (c && c != '#' && /* End of line or comment start */
c != '=' && /* end of keyword */
c != '|' &&
i < cfg_max_string_len)
{
if (c != ' ' && c != '\t') /* Ignore spaces and tabs */
{
cfg_string_buf[i] = c;
++i;
}
c = cfg_line_buf[cfg_line_offset++];
}
if (i >= cfg_max_string_len)
{
CFG_LOG_ERR1 ("Error : Line %d too long", cfg_curr_line);
return (SD_FAILURE);
}
if (c == '#' || !c) /* See if we need a new line next time */
cfg_need_new_line = SD_TRUE;
/* i is the index to the char position that terminated the scan */
cfg_string_buf[i]=0x0; /* NULL terminate the keyword */
/* if we have a keyword, then search look it up in the currently active */
/* keyword table and execute the selected function */
if (strlen (cfg_string_buf))
{ /* Find the keyword */
if ((ptr = cfg_lookup_keyword (curr_table, cfg_string_buf)) != NULL)
{
CFG_LOG_CFLOW1 ("Keyword : %s",cfg_string_buf);
(*ptr->extract)();
break;
}
else /* invalid keyword */
{
CFG_LOG_ERR1 ("Unknown Keyword : %s",cfg_string_buf);
return (SD_FAILURE);
}
}
} /* While SD_TRUE */
return(SD_SUCCESS);
}
/************************************************************************/
/* cfg_get_rval() */
/************************************************************************/
static ST_CHAR *cfg_get_rval(ST_VOID)
{
ST_INT i;
ST_CHAR c;
cfg_string_buf[0]=0x0;
/* Now get the rval (value). */
/* search for 0 to note end of line */
i = 0;
c = cfg_line_buf[cfg_line_offset++];
/* First strip leading white space (' ', '\t') */
while (c == ' ' || c == '\t')
c = cfg_line_buf[cfg_line_offset++];
while (c &&
c != '#' &&
!cfg_end_of_rval (c) &&
i < cfg_max_rval_len-1)
{
if (isalnum (c) || cfg_special_char (c))
{
cfg_string_buf[i] = c;
++i;
}
c = cfg_line_buf[cfg_line_offset++];
}
if (c == '#' || !c) /* See if we need a new line next time */
cfg_need_new_line = SD_TRUE;
/* Strip trailing spaces and tabs */
while (i && (cfg_string_buf[i-1] == ' ' ||
cfg_string_buf[i-1] == '\t'))
i--;
/* Null terminate the string */
cfg_string_buf[i] = 0x0;
if (!strlen (cfg_string_buf))
{
CFG_LOG_ERR2 ("Bad rval, line #%d \"%s\"",cfg_curr_line,cfg_line_buf);
return (NULL);
}
CFG_LOG_CFLOW1 ("Rval : '%s'",cfg_string_buf);
return (cfg_string_buf);
}
/************************************************************************/
/* cfg_lookup_keyword */
/************************************************************************/
static struct cfg_kw_el *cfg_lookup_keyword(struct cfg_kw_el *tbl_ptr,
ST_CHAR *name)
{
ST_INT i;
struct cfg_kw_el *ret = NULL;
for (i = 0; i < MAX_NUM_KEYWORDS; ++i)
{
if (tbl_ptr[i].extract == NULL) /* End of table */
break;
else if (!strcmpi (name, tbl_ptr[i].name))
{ /* we have a match */
if (tbl_ptr[i].valid !=NULL) /* Want to validate? */
{
if ((*tbl_ptr[i].valid)())
ret = &tbl_ptr[i];
}
else
ret = &tbl_ptr[i];
break;
}
}
return(ret);
}
/************************************************************************/
/* cfg_end_of_rval */
/************************************************************************/
/* CONFIG calls back to this function while looking the rval over */
/* If this function returns SD_TRUE, CONFIG will assume that the */
/* character is a keyword/rval pair seperator */
/* Used to allow multiple pairs per line */
static ST_RET cfg_end_of_rval (ST_CHAR c)
{
ST_INT i;
ST_INT str_len;
str_len = strlen (cfg_end_of_rval_str);
for (i = 0; i < str_len; ++i)
{
if (c == cfg_end_of_rval_str[i])
return (SD_TRUE);
}
return (SD_FALSE);
}
/************************************************************************/
/* cfg_special_char */
/************************************************************************/
static ST_RET cfg_special_char (ST_CHAR c)
{
ST_INT i;
ST_INT str_len;
str_len = strlen (cfg_special_char_str);
for (i = 0; i < str_len; ++i)
{
if (c == cfg_special_char_str[i])
return (SD_TRUE);
}
return (SD_FALSE);
}
/************************************************************************/
/************************************************************************/
/************************************************************************/
/* cfg_tbl_push (new_table) */
/************************************************************************/
ST_RET cfg_tbl_push (struct cfg_kw_el *new_table)
{
if (num_on_stack >= MAX_CONFIG_NEST)
{
CFG_LOG_ERR0 ("Too many pushes - configuration nesting exceeded");
config_stop = SD_TRUE;
config_err = CFG_UTIL_ERR;
return (SD_FAILURE);
}
cfg_kw_stack[num_on_stack] = new_table;
++num_on_stack;
curr_table = new_table;
return (SD_SUCCESS);
}
/************************************************************************/
/* cfg_tbl_pop (num_to_pop) */
/************************************************************************/
ST_RET cfg_tbl_pop (ST_INT num_to_pop)
{
if ((num_on_stack-num_to_pop-1)<0)
{
CFG_LOG_ERR0 ("Too many pops off configuration stack");
config_stop = SD_TRUE;
config_err = CFG_UTIL_ERR;
return (SD_FAILURE);
}
num_on_stack -= num_to_pop;
curr_table = cfg_kw_stack[num_on_stack-1];
return (SD_SUCCESS);
}
/************************************************************************/
/* cfg_get_short */
/************************************************************************/
ST_RET cfg_get_short (ST_INT16 *out_ptr)
{
ST_INT d;
ST_INT16 ret;
ret = cfg_get_value ("%d", &d);
if (!ret)
*out_ptr = (ST_INT16) d;
return (ret);
}
/************************************************************************/
/* cfg_get_ushort */
/************************************************************************/
ST_RET cfg_get_ushort (ST_UINT16 *out_ptr)
{
ST_UINT d;
ST_RET ret;
ret = cfg_get_value ("%u", &d);
if (!ret)
*out_ptr = (ST_UINT16) d;
return (ret);
}
/************************************************************************/
/* cfg_get_int */
/************************************************************************/
ST_RET cfg_get_int (ST_INT *out_ptr)
{
ST_INT d;
ST_RET ret;
ret = cfg_get_value ("%d", &d);
if (!ret)
*out_ptr = d;
return (ret);
}
/************************************************************************/
/* cfg_get_uint */
/************************************************************************/
ST_RET cfg_get_uint (ST_UINT *out_ptr)
{
ST_UINT d;
ST_RET ret;
ret = cfg_get_value ("%u", &d);
if (!ret)
*out_ptr = d;
return (ret);
}
/************************************************************************/
/* cfg_get_long */
/************************************************************************/
ST_RET cfg_get_long (ST_LONG *out_ptr)
{
return (cfg_get_value ("%ld", out_ptr));
}
/************************************************************************/
/* cfg_get_ulong */
/************************************************************************/
ST_RET cfg_get_ulong (ST_ULONG *out_ptr)
{
return (cfg_get_value ("%lu", out_ptr));
}
/************************************************************************/
/* cfg_get_double */
/************************************************************************/
ST_RET cfg_get_double (ST_DOUBLE *out_ptr)
{
return (cfg_get_value ("%lf", out_ptr));
}
/************************************************************************/
/* cfg_get_hex_ushort */
/************************************************************************/
ST_RET cfg_get_hex_ushort (ST_UINT16 *out_ptr)
{
ST_UINT d;
ST_RET ret;
ret = cfg_get_value ("%x", &d);
if (!ret)
*out_ptr = (ST_UINT16) d;
return (ret);
/* return (cfg_get_value ("%x", out_ptr)); */
}
/************************************************************************/
/* cfg_get_hex_uint */
/************************************************************************/
ST_RET cfg_get_hex_uint (ST_UINT *out_ptr)
{
ST_UINT d;
ST_RET ret;
ret = cfg_get_value ("%x", &d);
if (!ret)
*out_ptr = d;
return (ret);
/* return (cfg_get_value ("%x", out_ptr)); */
}
/************************************************************************/
/* cfg_get_hex_ulong */
/************************************************************************/
ST_RET cfg_get_hex_ulong (ST_ULONG *out_ptr)
{
return (cfg_get_value ("%lx", out_ptr));
}
/************************************************************************/
/* cfg_get_value */
/************************************************************************/
ST_RET cfg_get_value (ST_CHAR *format_string, ST_VOID *out_ptr)
{
ST_CHAR *rval;
rval = cfg_get_rval (); /* get the rvalue string */
if (!rval)
{
config_err = CFG_GET_RVAL_ERR;
CFG_LOG_ERR0 ("Get Rval Error");
}
else
{ /* Convert to desired data format*/
if (!sscanf (rval,format_string,out_ptr))
{
config_err = CFG_CONVERT_ERR;
CFG_LOG_ERR0 ("Data Conversion Error");
}
}
if (config_err) /* if error detected ... */
{
config_stop = SD_TRUE;
return (SD_FAILURE);
}
return (SD_SUCCESS);
}
/************************************************************************/
/************************************************************************/
/* *cfg_get_alloc_string */
/************************************************************************/
ST_CHAR *cfg_get_alloc_string (ST_VOID)
{
ST_CHAR *ret_ptr;
ST_CHAR *rval;
rval = cfg_get_rval (); /* get the rvalue string */
if (!rval)
{
config_stop = SD_TRUE;
config_err = CFG_GET_RVAL_ERR;
CFG_LOG_ERR0 ("Get Rval Error");
return (NULL);
}
/* allocate storage for string */
ret_ptr = (ST_CHAR *) chk_calloc (1,strlen (rval) +1);
strcpy (ret_ptr,rval);
return (ret_ptr);
}
/************************************************************************/
/* *cfg_get_string_ptr */
/************************************************************************/
ST_CHAR *cfg_get_string_ptr (ST_VOID)
{
ST_CHAR *rval;
rval = cfg_get_rval (); /* get the rvalue string */
if (!rval)
{
config_stop = SD_TRUE;
config_err = CFG_GET_RVAL_ERR;
CFG_LOG_ERR0 ("Get Rval Error");
return (NULL);
}
return (rval);
}
/************************************************************************/
/* cfg_get_octet_string */
/************************************************************************/
ST_RET cfg_get_octet_string (ST_UCHAR *ostr, /* ptr to user's ostr */
ST_UINT *len_out_ptr, /* addr of len var to be set */
ST_UINT len_max) /* maximum len to allow. */
{
ST_UINT j;
ST_INT digit;
ST_BOOLEAN nibble; /* SD_TRUE if nibble read, SD_FALSE if whole byte read*/
ST_CHAR *rval;
rval = cfg_get_rval (); /* get the rvalue string */
if (!rval)
{
config_stop = SD_TRUE;
config_err = CFG_GET_RVAL_ERR;
CFG_LOG_ERR0 ("Get Rval Error");
return (SD_FAILURE);
}
j = 0;
nibble = SD_FALSE;
while (isxdigit (*rval)) /* get hex number */
{
if (j >= len_max)
return (SD_FAILURE); /* Selector longer than allowed */
digit = *rval++; /* separate nibbles */
digit = isdigit (digit) ? digit - '0' : 10 + (toupper (digit) - 'A');
if (nibble)
{
nibble = SD_FALSE;
ostr[j] = (ostr[j] | (ST_UCHAR) digit); /* set low */
j++;
while (isspace (*rval) && *rval != '\n')
++rval;
}
else
{
nibble = SD_TRUE;
ostr[j] = (ST_UCHAR) digit << 4; /* set high byte */
}
}
if (nibble)
{ /* Only got half of byte. */
config_stop = SD_TRUE;
config_err = CFG_CONVERT_ERR;
CFG_LOG_ERR0 ("Incomplete byte in Octet string");
return (SD_FAILURE);
}
/* set selector length */
*len_out_ptr = j;
return (SD_SUCCESS);
}
/************************************************************************/
/* cfg_set_config_err */
/************************************************************************/
ST_VOID cfg_set_config_err(ST_VOID)
{
config_err = SD_TRUE;
}
/************************************************************************/
/* cfg_set_endfile_ok */
/************************************************************************/
ST_VOID cfg_set_endfile_ok(ST_VOID)
{
config_eof = SD_SUCCESS;
}
/************************************************************************/
/************************************************************************/
/* cfg_goto_keyword */
/************************************************************************/
/* This function is used to skip over a section to the specified keyword*/
ST_RET cfg_goto_keyword (ST_CHAR *keyword)
{
ST_INT i, cfgStringLen, keywordLen;
ST_CHAR c;
/* Look for 'yyy =' string */
keywordLen = strlen (keyword);
while (SD_TRUE) /* While looking for the specified word */
{
if (cfg_need_new_line)
{
if ( fgets( cfg_line_buf, cfg_line_buf_size - 1, config_fptr ) == NULL )
{
CFG_LOG_CFLOW0 ("No More Keywords : End Of File");
/* The following piece of logic exists to allow the state functions to */
/* declare when it is ok for the file to be out of keywords. If a user */
/* state function set 'config_eof == SD_SUCCESS' then config_stop is set */
/* to true when ENDFILE is encountered. */
if ( config_eof == SD_SUCCESS )
{
config_stop = SD_TRUE;
}
return( SD_FAILURE );
}
/* Wack the \n */
for (i = 0; i < cfg_line_buf_size; ++i)
{
if (cfg_line_buf[i] == '\n')
{
cfg_line_buf[i] = 0;
break;
}
}
cfg_line_offset = 0; /* Offset is 0 for new line */
++cfg_curr_line;
if (cfg_line_buf[0] == '#')
continue; /* Discard comment lines */
cfg_need_new_line = SD_FALSE; /* Got a new line */
}
/* We now have a line to work on, with cfg_line_offset the 1st char */
/* Extract the keyword from the string (alpha numeric characters) */
/* '=' means end of rval */
/* 0 is end of line */
i = 0;
c = cfg_line_buf[cfg_line_offset++];
while (c && c != '#' && /* End of line or comment start */
c != '=' && /* end of keyword */
c != '|' &&
i < cfg_max_string_len)
{
if (c != ' ' && c != '\t') /* Ignore spaces and tabs */
{
cfg_string_buf[i] = c;
++i;
}
c = cfg_line_buf[cfg_line_offset++];
}
if (i >= cfg_max_string_len)
{
CFG_LOG_ERR1 ("Error : Line %d too long", cfg_curr_line);
return (SD_FAILURE);
}
if (c == '#' || !c) /* See if we need a new line next time */
cfg_need_new_line = SD_TRUE;
/* i is the index to the char position that terminated the scan */
cfg_string_buf[i]=0x0; /* NULL terminate the keyword */
/* if we have a keyword, then search look it up in the currently active */
/* keyword table and execute the selected function */
if ((cfgStringLen = strlen (cfg_string_buf)) > 0)
{ /* Find the keyword */
if ((cfgStringLen == keywordLen) && !strcmpi (keyword, cfg_string_buf))
break;
else /* keyword not found */
cfg_need_new_line = SD_TRUE;
}
} /* While SD_TRUE */
return(SD_SUCCESS);
}

464
mmslib/util/genlists.c Normal file
View File

@@ -0,0 +1,464 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1986-2005 All Rights Reserved */
/* */
/* MODULE NAME : gen_list.c */
/* PRODUCT(S) : general list handling functions */
/* */
/* MODULE DESCRIPTION : */
/* This module contains generic que manipulation routines */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 10/04/07 MDE 07 Tweaked LOGCFG_VALUE_GROUP/LOGCFGX_VALUE_MAP */
/* 06/30/05 EJV 06 Add genlistDebugMaps, genlistDebugMapCtrl */
/* for parsing logcfg.xml */
/* 04/08/04 JRB 05 list_find_last: if head=NULL, don't log. */
/* 12/12/02 JRB 04 list_get_first/last: if *head==NULL, return */
/* NULL & do NOT log a message. */
/* 11/21/01 MDE 03 Changed logging to use SLOGALWAYS */
/* 10/09/98 JRB 02 Add list_find_prev, list_find_last. */
/* 06/15/98 MDE 01 Changes to allow compile under C++ */
/* 04/02/97 DTL 7.00 MMSEASE 7.0 release. See MODL70.DOC for */
/* history. */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#define I_AM_THE_TRUE_GEN_LIST
#include "gen_list.h"
#include "slog.h"
/************************************************************************/
/************************************************************************/
/* For debug version, use a static pointer to avoid duplication of */
/* __FILE__ strings. */
/************************************************************************/
#ifdef DEBUG_SISCO
static ST_CHAR *thisFileName = __FILE__;
#endif
/************************************************************************/
/* The variable below is used in selecting generic queuing debug */
/* checking. When this variable is set to SD_TRUE all data strucutres */
/* using the list manipulation primitives will under go this checking */
ST_BOOLEAN list_debug_sel;
#ifdef DEBUG_SISCO
LOGCFGX_VALUE_MAP genlistDebugMaps[] =
{
/* Memory debugging */
{"ListDebugSel", 0, &list_debug_sel, _LOGCFG_DATATYPE_BOOLEAN, NULL, NULL}
};
LOGCFG_VALUE_GROUP genlistDebugMapCtrl =
{
{NULL,NULL},
"GenListLogMasks", /* Parent Tag */
sizeof(genlistDebugMaps)/sizeof(LOGCFGX_VALUE_MAP),
genlistDebugMaps
};
#endif /* DEBUG_SISCO */
/************************************************************************/
/* list_unlink */
/* Primitive to unlink a node out of a circular double linked list */
/************************************************************************/
ST_RET list_unlink (DBL_LNK **list_head_ptr, DBL_LNK *node_ptr)
{
#ifdef DEBUG_SISCO
if (*list_head_ptr == NULL)
{
SLOGALWAYS0 ("GENLIST: ATTEMPT TO UNLINK A NODE FROM A NULL LIST");
return (SD_FAILURE);
}
if (node_ptr == NULL)
{
SLOGALWAYS0 ("GENLIST: ATTEMPT TO UNLINK A NULL ADDRESS FROM A LIST");
return (SD_FAILURE);
}
if (list_debug_sel == SD_TRUE)
{
if (list_find_node (*list_head_ptr, node_ptr) == SD_FAILURE)
{
SLOGALWAYS0 ("GENLIST: NODE NOT FOUND IN LIST");
return (SD_FAILURE);
}
}
#endif
/* If list checking is enabled and we get to here we have valid */
/* arguments and a valid list */
if ((node_ptr -> next == *list_head_ptr) &&
(node_ptr == *list_head_ptr)) /* only node in list? */
{
*list_head_ptr = NULL;
}
else
{
if (node_ptr == *list_head_ptr) /* first node in a multi*/
*list_head_ptr = node_ptr->next; /* node list */
(node_ptr->next)->prev = node_ptr->prev; /* link cur next to prev*/
(node_ptr->prev)->next = node_ptr->next; /* link cur prev to next*/
}
return (SD_SUCCESS);
}
/************************************************************************/
/* list_add_first */
/* Primitive to add a node as the first node of a circular double */
/* linked list */
/************************************************************************/
ST_RET list_add_first (DBL_LNK **list_head_ptr, DBL_LNK *node_ptr)
{
DBL_LNK *list_tail_ptr;
#ifdef DEBUG_SISCO
if (node_ptr == NULL)
{
SLOGALWAYS0 ("GENLIST: ATTEMPT TO ADD A NULL ADDRESS TO A LIST");
return (SD_FAILURE);
}
#endif
/* If list checking is enabled and we get to here we have valid */
/* arguments */
if (*list_head_ptr == NULL) /* will this be the only node? */
{
node_ptr->next = node_ptr;
node_ptr->prev = node_ptr;
}
else
{
list_tail_ptr = (*list_head_ptr)->prev;
node_ptr->next = *list_head_ptr;
node_ptr->prev = list_tail_ptr;
list_tail_ptr->next = node_ptr;
(*list_head_ptr)->prev = node_ptr;
}
*list_head_ptr = node_ptr; /* assign the new head of list */
return (SD_SUCCESS);
}
/************************************************************************/
/* list_add_last */
/* Primitive to add a node as the last node of a circular double */
/* linked list */
/************************************************************************/
ST_RET list_add_last (DBL_LNK **list_head_ptr, DBL_LNK *node_ptr)
{
DBL_LNK *list_tail_ptr;
#ifdef DEBUG_SISCO
if (node_ptr == NULL)
{
SLOGALWAYS0 ("GENLIST: ATTEMPT TO ADD A NULL ADDRESS TO A LIST");
return (SD_FAILURE);
}
#endif
/* If list checking is enabled and we get to here we have valid */
/* arguments */
if (*list_head_ptr == NULL) /* will this be the only node? */
{
node_ptr->next = node_ptr;
node_ptr->prev = node_ptr;
*list_head_ptr = node_ptr;
}
else
{
list_tail_ptr = (*list_head_ptr)->prev;
list_tail_ptr->next = node_ptr;
node_ptr->prev = list_tail_ptr;
node_ptr->next = *list_head_ptr;
(*list_head_ptr)->prev = node_ptr;
}
return (SD_SUCCESS);
}
/************************************************************************/
/* list_get_first */
/* Primitive to unlink the first node out of the list and return it's */
/* address */
/************************************************************************/
#ifndef FASTLIST
ST_VOID *list_get_first (DBL_LNK **list_head_ptr)
{
DBL_LNK *node_ptr;
if (*list_head_ptr == NULL)
return (NULL);
node_ptr = *list_head_ptr;
list_unlink (list_head_ptr, node_ptr);
return (node_ptr);
}
#endif
/************************************************************************/
/* list_get_last */
/* Primitive to unlink the last node out of the list and return it's */
/* address */
/************************************************************************/
ST_VOID *list_get_last (DBL_LNK **list_head_ptr)
{
DBL_LNK *node_ptr;
if (*list_head_ptr == NULL)
return (NULL);
node_ptr = *list_head_ptr;
node_ptr = node_ptr->prev;
list_unlink (list_head_ptr, node_ptr);
return (node_ptr);
}
/************************************************************************/
/* list_move_to_first */
/* Primitive to unlink the first node out of the list and return it's */
/* address */
/************************************************************************/
ST_RET list_move_to_first (DBL_LNK **src_list_head_ptr,
DBL_LNK **dest_list_head_ptr,
DBL_LNK *node_ptr)
{
ST_RET ret_code;
if (!(ret_code = list_unlink (src_list_head_ptr, node_ptr)))
{
list_add_first (dest_list_head_ptr, node_ptr);
}
return (ret_code);
}
/************************************************************************/
/* list_find_node */
/* Primitive to verify that a node is in a list, returns SD_SUCCESS if it */
/* is; SD_FAILURE otherwise. */
/************************************************************************/
ST_RET list_find_node (DBL_LNK *list_head_ptr, DBL_LNK *node_ptr)
{
DBL_LNK *temp_ptr;
DBL_LNK *list_tail_ptr;
ST_RET ret_code;
if ((list_head_ptr == NULL) || (node_ptr == NULL))
ret_code = SD_FAILURE;
else
{
temp_ptr = list_head_ptr;
list_tail_ptr = list_head_ptr->prev;
/* search forward from the begining to the end of the list for our node */
while ((temp_ptr != list_tail_ptr) && (temp_ptr != node_ptr))
{
temp_ptr = temp_ptr->next;
}
if (temp_ptr == node_ptr)
ret_code = SD_SUCCESS;
else
ret_code = SD_FAILURE;
}
return (ret_code);
}
/************************************************************************/
/* list_print_links */
/************************************************************************/
#if 0
ST_VOID list_print_links (DBL_LNK *list_head_ptr)
{
DBL_LNK *temp_ptr;
DBL_LNK *list_tail_ptr;
ST_INT i;
i = 1;
if (list_head_ptr == NULL)
{
printf ("\nThe list is empty");
}
else
{
temp_ptr = list_head_ptr;
list_tail_ptr = list_head_ptr->prev;
printf ("\npointer to the head of the list is: %lx",list_head_ptr);
printf ("\n");
printf ("\npointer to node number %d is: %lx",i, temp_ptr);
printf ("\nnode number: next ptr is: %lx",temp_ptr->next);
printf ("\n prev ptr is: %lx",temp_ptr->prev);
while ((temp_ptr != list_tail_ptr))
{
temp_ptr = temp_ptr->next;
i++;
printf ("\npointer to node number %d is: %lx",i, temp_ptr);
printf ("\nnode number: next ptr is: %lx",temp_ptr->next);
printf ("\n prev ptr is: %lx",temp_ptr->prev);
}
}
}
#endif
/************************************************************************/
/* list_add_node_after(list insert node prim) */
/* Primitive to add a node to a list after the current node. This */
/* function assumes that we are working with a non NIL list. SD_SUCCESS */
/* is returned if the node gets added to the list; SD_FAILURE otherwise. */
/************************************************************************/
ST_RET list_add_node_after (DBL_LNK *cur_node, DBL_LNK *new_node)
{
DBL_LNK *next_node;
ST_RET ret_val;
ret_val = SD_FAILURE;
if (new_node == NULL)
{
SLOGALWAYS0 ("GENLIST: ATTEMPT TO ADD A NULL ADDRESS TO A LIST");
}
else if (cur_node == NULL)
{
SLOGALWAYS0 ("GENLIST: ATTEMPT TO ADD A NODE TO A NULL LIST");
}
else /* this is a good node and good predecessor */
{
next_node = cur_node -> next;
new_node -> next = next_node;
new_node -> prev = cur_node;
next_node -> prev = new_node;
cur_node -> next = new_node;
ret_val = SD_SUCCESS;
}
return (ret_val);
}
/************************************************************************/
/* list_get_next */
/* Primitive to get the node pointed to by the next component of the */
/* current node. This function returns NULL if the list_head_ptr is */
/* NULL, the address of the current node is NULL or the next node in the*/
/* list is the list_head_ptr(the list has wrapped around). This */
/* function is useful for traversing a doubly linked circular list */
/* from begining to the end as if the list were NULL terminated. */
/************************************************************************/
#ifndef FASTLIST
ST_VOID *list_get_next (DBL_LNK *list_head_ptr, DBL_LNK *cur_node)
{
DBL_LNK *next_node = NULL;
if (list_head_ptr == NULL)
{
SLOGALWAYS0 ("GENLIST: ATTEMPT TO REFERENCE A NULL LIST");
}
else if (cur_node == NULL)
{
SLOGALWAYS0 ("GENLIST: ATTEMPT TO REFERENCE THROUGH A NULL PTR");
}
else if (cur_node->next != list_head_ptr)
{
next_node = cur_node->next;
}
return (next_node);
}
#endif
/************************************************************************/
/* list_get_sizeof */
/* Primitive to return the number of nodes in this generic list. */
/************************************************************************/
ST_INT list_get_sizeof (DBL_LNK *list_head_ptr)
{
ST_INT count;
DBL_LNK *cur_node;
count = 0;
cur_node = list_head_ptr;
while (cur_node != NULL)
{
count ++;
cur_node = (DBL_LNK *) list_get_next (list_head_ptr, cur_node);
}
return (count);
}
/************************************************************************/
/* list_find_prev */
/* Primitive to find the node "before" the current node in the linked */
/* list. This function returns NULL if the list_head_ptr is */
/* NULL, the current node is NULL, or the current node */
/* is the head of the linked list (i.e. does not wrap around). */
/************************************************************************/
DBL_LNK *list_find_prev (DBL_LNK *list_head_ptr, DBL_LNK *cur_node)
{
DBL_LNK *prev_node = NULL;
if (list_head_ptr == NULL)
{
SLOGALWAYS0 ("GENLIST: ATTEMPT TO REFERENCE A NULL LIST");
}
else if (cur_node == NULL)
{
SLOGALWAYS0 ("GENLIST: ATTEMPT TO REFERENCE THROUGH A NULL PTR");
}
else if (cur_node != list_head_ptr)
{
prev_node = cur_node->prev;
}
return (prev_node);
}
/************************************************************************/
/* list_find_last */
/* Primitive to find the last node in the linked list and return it's */
/* address. */
/************************************************************************/
DBL_LNK *list_find_last (DBL_LNK *list_head_ptr)
{
DBL_LNK *last_node;
if (list_head_ptr)
last_node = list_head_ptr->prev;
else
{ /* head is NULL (i.e. list is empty) so last is NULL too. */
last_node = NULL;
}
return (last_node);
}

2814
mmslib/util/gensock2.c Normal file

File diff suppressed because it is too large Load Diff

462
mmslib/util/glbsem.c Normal file
View File

@@ -0,0 +1,462 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1997-2005, All Rights Reserved */
/* */
/* MODULE NAME : glbsem.c */
/* PRODUCT(S) : */
/* */
/* MODULE DESCRIPTION : Multi-thread support. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 03/12/08 JRB 77 gs_free_semx: make sure fname initialized. */
/* 10/04/07 MDE 76 Tweaked LOGCFG_VALUE_GROUP/LOGCFGX_VALUE_MAP */
/* 05/23/07 NAV 75 gs_get_semx: conditionally call sGetMsTime */
/* 02/13/06 DSF 74 Migrate to VS.NET 2005 */
/* 06/17/05 EJV 73 UNIX, Linux: need str_util.h */
/* 06/10/05 DSF 72 Added an array to track calls to gs_free_semx*/
/* 06/07/05 EJV 71 Added S_MT_SUPPORT to avoid Linux errors. */
/* 05/23/05 EJV 70 Add gsLogMaskMapCtrl for parsing logcfg.xml */
/* Moved gs_debug_sel from slog.c. */
/* 05/23/05 JRB 69 Move all gs_timer* functions to glbtimer.c */
/* 02/22/05 EJV 68 gs_timer_worker_thread: eliminated warnings */
/* 01/10/05 DSF 67 Signal timer event after timer object is */
/* unlinked */
/* Don't call user callback if timer is */
/* terminated */
/* 08/23/04 EJV 66 GS_TIMER: rpl elapsed w/ ST_DOUBLE expiration*/
/* 07/23/04 DSF 65 Set names of timer threads */
/* 07/22/04 DSF 64 Set timer resolution back to 10 */
/* 07/02/04 EJV 63 gs_timer_thread: chg sleep from 10 to 0 ms. */
/* 06/17/04 DSF 62 Reset gs_timer_thread_stop in gs_timer_init()*/
/* 05/05/04 EJV 61 gs_timer_cleanup: added timeout parameter. */
/* Added timer worker threads to proc callbacks.*/
/* gs_timer_init: added min_workers, max_workers*/
/* 04/22/04 DSF 60 Initialized timer resolution to 1000 ms */
/* 01/21/04 EJV 59 Win Timers: changed to use UNIX code. */
/* Win impl preserved with _WIN32_timers define */
/* 12/01/03 EJV 58 gs_is_win_ver: chk for corr ret 1, 0, -1. */
/* 11/17/03 EJV 57 gs_timer_end: reverted moved gs_timer_remove.*/
/* _WIN32: reworked periodic timers >430000ms; */
/* All timer_id will go on delayed delete list*/
/* 10/15/03 JRB 56 Move gs_debug_sel to slog.c, slogl.c. */
/* 10/09/03 JRB 55 Enable gs_timer* functions for ALL systems. */
/* 07/29/03 DSF,EJV 54 gs_timer_end: moved gs_timer_remove fun up. */
/* 06/20/03 EJV 53 Del param from gs_mutex_get, gs_get_semx. */
/* 06/12/03 EJV 52 Redesigned mutex sems implementation. */
/* 06/06/03 JRB 51 Move _WIN32 code to new glbsem_w32.c */
/* Move UNIX code to new glbsem_unix.c */
/* Del OS2 code & "default" code. */
/* Del unused gs_*_sig functions for DEC UNIX. */
/* Add gs_util_mutex, init it in gs_init. */
/* Chg GLBSEM_LOG_ALWAYS* to SLOGALWAYS*. */
/* 06/03/03 EJV 50 _WIN32: changed for 64-bit compiler: */
/* last param cast in RaiseException */
/* gs_timer_callback last 3 parms to DWORD_PTR*/
/* 04/14/03 JRB 49 Del intermediate functions for mutexes, */
/* macros in glbsem.h use gs_mutex_get/free. */
/* assert if gs_init fails (no way to recover). */
/* 04/04/03 JRB 48 Chg _ASSERTE calls to assert, otherwise must */
/* link DebugMultithreaded libs on Windows. */
/* 03/24/03 EJV 47 Removed logging from some MUTEX functions. */
/* gs_get_sem, gs_get_semx: added ASSERTE. */
/* 02/03/03 EJV 46 _WIN32: added gs_is_win_ver() */
/* added gs_get_named_event_sem() */
/* 01/24/03 EJV 45 _WIN32 gs_start_thread: added comment. */
/* 01/14/03 EJV 44 Added gs_sleep(). */
/* 11/01/02 EJV 43 Use SISCO's link list with timers. */
/* 10/30/02 EJV 42 gs_timer_check_list: limit delay to 1 sec. */
/* Check if callback pending before deleting. */
/* 10/31/02 EJV 41 gs_wait_mult_event_sem: corr activity memset */
/* 07/29/02 EJV 40 Added gs_timer_get_resolution(), */
/* Corrected timer termination wait. */
/* Reverted timer _WIN32, added ptr wait list */
/* 02/06/02 EJV 39 Compile this module if S_MT_SUPPORT defined */
/* 12/04/01 KCR 38 cleared activity[] in gs_wait_mult_event_sem */
/* 10/31/01 EJV 37 _WIN32: changed to call _beginthreadex; */
/* Added gs_close_thread, gs_pulse_event_sem. */
/* Replaced _ALWAYS macros with _ERR or _NERR. */
/* _WIN32: gs_wait_thread now returns SD_FAILURE*/
/* on timeout. */
/* UNIX: gs_reset_event_sem now clears predicate*/
/* 10/18/01 JRB 36 Eliminate warning. */
/* 09/20/01 EJV 35 _WIN32 gs_timer_callback: check if pending */
/* 08/01/01 JRB 34 gs_get_semx fill in fname even if NOT logging*/
/* 07/30/01 EJV 33 Added gs_timer_set_resolution() fun. */
/* _WIN32: reworked gs_timer functions. */
/* 07/25/01 EJV 32 Changed gs_timer_resolution from 1000 to 10ms*/
/* 07/24/01 EJV 31 _WIN32: added gs_timer support. */
/* 05/17/01 EJV 30 _WIN32: eliminated compile warnings. */
/* 04/04/01 DSF 29 Added gs_set_thread_name for WIN32 */
/* 03/27/01 EJV 28 UNIX: gs_wait_event_sem, mutex the whole fun */
/* 03/16/01 EJV 27 UNIX: added check to gs_free_event_sem. */
/* UNIX: set thread attribute to joinable. */
/* Removed #undef NDEBUG (now in make file) */
/* 03/12/01 EJV 26 UNIX: added/changed few FLOW slogs. */
/* UNIX: corr gs_wait_event_sem, predicate=0 */
/* Removed <assert.h>, already in sysincs.h */
/* Changed assert to _ASSERTE - def in sysincs.h*/
/* 03/08/01 EJV 25 UNIX: Corrected type to ST_BOOLEAN for */
/* static var gs_timer_thread_stop. Corr logs. */
/* 03/07/01 EJV 24 UNIX: init attr before calling create thread.*/
/* In gs_wait_event_sem check for predicate=1 */
/* before entering the wait. */
/* 02/19/01 EJV 23 _AIX: eliminated need to call gs_timer_init. */
/* 02/14/01 EJV 22 Removed some DEBUG_SISCO around slog macros */
/* AIX: added timer functions gs_timer_xxx. */
/* 01/16/01 EJV 21 Moved GET_THREAD_ID define to glbsem.h */
/* 12/27/00 EJV 20 _WIN32: Renamed glbCritSetion for easy calls.*/
/* Added check for gs_already_inited. */
/* 12/20/00 EJV 19 Ported to AIX. Revised DEC UNIX. */
/* 12/13/00 EJV 18 Added gs_mutex_... user mutex functions. */
/* Added gs_track for faster SISCO MUTEX. */
/* Removed currSemOwner, semCount */
/* Added few DEBUG_SISCO for __alpha. */
/* 12/06/00 EJV 17 Changed gs_get_event_sem to accept arg. */
/* USE_MANUAL_RESET_SEM define not necessary. */
/* 10/25/00 JRB 16 Del gs_chk_thread_id. Found better way to */
/* prevent errors (see "_MT" chk in glbsem.h). */
/* 10/06/00 EJV 15 Ported to DEC UNIX (__alpha) pthread funcs. */
/* Deleted unused: myThreadId,... */
/* 10/06/00 EJV 14 _WIN32: corrected logging statements */
/* 04/27/00 MDE 13 Lint cleanup */
/* 03/14/00 JRB 12 Chg to allow breakpoint before assert. */
/* 01/21/00 JRB 11 Del gs_install. Del function pointers. */
/* gs_get_sem call gs_init if not already done. */
/* Add "gs_chk_thread_id". */
/* 12/16/99 NAV 10 in gs_free_semx watch for GS_LOG_FLOW */
/* 09/13/99 MDE 09 Added SD_CONST modifiers */
/* 08/05/99 JRB 08 Chged "gs_get_event_sem" to "auto-reset" */
/* unless USE_MANUAL_RESET_SEM defined. */
/* #ifdef'd out "gs_reset_event_sem". */
/* Added partial support for __OS2__. */
/* 03/01/99 DSF 07 Corrected #define releaseMutexSem for */
/* non-DEBUG_SISCO version */
/* 01/22/99 DSF 06 Use Critical Section instead of Mutex (faster)*/
/* 10/08/98 MDE 05 Migrated to updated SLOG interface */
/* 06/05/98 MDE 04 Fixed uninitialized 'rc' */
/* 05/05/98 DSF 03 Added SD_TIMEOUT */
/* 12/11/97 KCR 02 Added gs_wait_mult_event_sem for _WIN32 */
/* 10/27/97 EJV 01 For !_WIN32 implementations: */
/* Added typecast to define GET_THREAD_ID(); */
/* Changed func gs_get_event_sem return from */
/* from SD_FAILURE to (ST_EVENT_SEM) 0. */
/* 04/02/97 DTL 7.00 MMSEASE 7.0 release. See MODL70.DOC for */
/* history. */
/************************************************************************/
#if defined (_WIN32)
#pragma warning(disable : 4996)
#endif
#include "glbtypes.h"
#include "sysincs.h"
#include "mem_chk.h"
#include "slog.h"
#include "glbsem.h"
#include "str_util.h"
#if defined(S_MT_SUPPORT)
/************************************************************************/
/* For debug version, use a static pointer to avoid duplication of */
/* __FILE__ strings. */
#ifdef DEBUG_SISCO
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
#endif
/************************************************************************/
/************************************************************************/
/* GLOBAL VARIABLES */
ST_UINT gs_debug_sel = GS_LOG_ERR | GS_LOG_NERR;
#ifdef DEBUG_SISCO
SD_CONST ST_CHAR *SD_CONST _glbem_flow_logstr = "GS_LOG_FLOW";
SD_CONST ST_CHAR *SD_CONST _glbem_err_logstr = "GS_LOG_ERR";
SD_CONST ST_CHAR *SD_CONST _glbem_nerr_logstr = "GS_LOG_NERR";
LOGCFGX_VALUE_MAP gsLogMaskMaps[] =
{
{"GS_LOG_ERR", GS_LOG_ERR, &gs_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "Error"},
{"GS_LOG_NERR", GS_LOG_NERR, &gs_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "Notice"},
{"GS_LOG_FLOW", GS_LOG_FLOW, &gs_debug_sel, _LOGCFG_DATATYPE_UINT_MASK, NULL, "Flow"},
};
LOGCFG_VALUE_GROUP gsLogMaskMapCtrl =
{
{NULL,NULL},
"SemaphoreLogMasks", /* Parent Tag */
sizeof(gsLogMaskMaps)/sizeof(LOGCFGX_VALUE_MAP),
gsLogMaskMaps
};
#endif /* DEBUG_SISCO */
/* variables to evalueate semaphores locking performance */
ST_DOUBLE gs_hwMutexTime;
ST_DOUBLE gs_hwEventTime;
ST_MUTEX_SEM gs_glb_mutex; /* global SISCO MUTEX semaphore */
ST_MUTEX_SEM gs_util_mutex; /* UTILITY MUTEX semaphore: for "low-level"*/
/* util functs (slog,mem_chk,stime,etc.)*/
ST_BOOLEAN gs_already_inited = SD_FALSE;
#if defined(DEBUG_SISCO)
/* The debug version keeps a stack of sem owners call locations */
/* which can be logged to aid in debugging. */
/* These variables are only changed by a thread that owns the sem, but */
/* can be read (for logging) by 'gs_log_sem_state', possibly resulting */
/* in a 'torn' log if the called is not careful. */
#define MAX_SEM_NEST_TRACK 20
ST_UINT gs_track; /* This variable when set to value >0 */
/* during an application startup allows */
/* tracking of MUTEX or EVENT sem. */
ST_INT gs_currSemOwnerIndex;
ST_CHAR gs_currSemOwnerFile[MAX_SEM_NEST_TRACK][SLOG_MAX_FNAME+1];
ST_INT gs_currSemOwnerLine[MAX_SEM_NEST_TRACK];
ST_CHAR gs_currSemFreeFile[MAX_SEM_NEST_TRACK][SLOG_MAX_FNAME+1];
ST_INT gs_currSemFreeLine[MAX_SEM_NEST_TRACK];
#endif /* DEBUG_SISCO */
/*---*---*---*---*---*---*---*---*---*---*---*---*---*--*/
/* */
/* SISCO's GLOBAL MUTEX SEMAPHORE FUNCTIONS */
/* */
/*---*---*---*---*---*---*---*---*---*---*---*---*---*--*/
/************************************************************************/
/* gs_init */
/*----------------------------------------------------------------------*/
/* Initialize global SISCO MUTEX semaphore. */
/* This function will be called from the gs_get_sem or gs_get_semx, */
/* it does not have to be called from user application. */
/* Parameters: */
/* none */
/* Return values: */
/* SD_SUCCESS function successful */
/* SD_FAILURE error occurred */
/************************************************************************/
ST_RET gs_init (ST_VOID)
{
ST_RET rc;
/* !!! To avoid infinite loop with SLOG do not log from this function. */
if (gs_already_inited)
return (SD_SUCCESS);
/* WARNING: The gs_util_mutex should not be changed to use named mutex */
/* because logging in the code handling named mutex will cause */
/* infinite loop. */
/* Initialize the MUTEX semaphores. Both must succeed, so OR the returns.*/
rc = gs_mutex_create (&gs_glb_mutex);
rc |= gs_mutex_create (&gs_util_mutex);
/* Set up to track the semaphore owners by nesting level */
#if defined(DEBUG_SISCO)
gs_currSemOwnerIndex = -1;
#endif
if (rc == SD_SUCCESS)
gs_already_inited = SD_TRUE;
else
assert (0); /* nothing will work properly if this fails. */
return (rc);
}
/************************************************************************/
/* gs_log_sem_state */
/*----------------------------------------------------------------------*/
/* Log the global SISCO MUTEX semaphore owner stack. */
/* Parameters: */
/* none */
/* Return values: */
/* none */
/************************************************************************/
ST_VOID gs_log_sem_state (ST_VOID)
{
#if defined(DEBUG_SISCO)
ST_INT i;
if (!gs_already_inited) /* Make sure gs is initialized. */
return;
SLOGALWAYS0 ("GLBSEM: Semaphore owner stack (oldest to latest) :");
for (i = 0; i <= gs_currSemOwnerIndex && i < MAX_SEM_NEST_TRACK; ++i)
{
SLOGCALWAYS3 (" %d) File %s, Line %d",
i+1, gs_currSemOwnerFile[i], gs_currSemOwnerLine[i]);
}
if (gs_currSemOwnerIndex >= MAX_SEM_NEST_TRACK)
SLOGCALWAYS0 (" Sem's nested too deep to track further");
#endif
}
/************************************************************************/
/* gs_get_semx */
/*----------------------------------------------------------------------*/
/* Lock (obtain ownership) the global SISCO MUTEX semaphore. */
/* This debug version function keeps track of the sem owner stack. */
/* If compiled without DEBUG_SISCO it just falls through to gs_get_sem. */
/* If compiled with DEBUG_SISCO the gs_track variable need to be set to */
/* value >0 to enable the tracking code. This way logging can be used */
/* by an application without degradation of the MUTEX sem performance. */
/* In addition the gs_debug_sel need to be set to GS_LOG_FLOW to */
/* log the tracking results. */
/* Parameters: */
/* srcFile ptr to source code file name calling this fun */
/* srcLineNum source code line number */
/* Return values: */
/* none */
/* CRITICAL: gs_get_semx must NOT be called from any slog or stime */
/* functions. It calls slog and stime functions which would cause */
/* an infinite loop. Slog and stime must call gs_mutex_get. */
/************************************************************************/
ST_VOID gs_get_semx (SD_CONST ST_CHAR *srcFile, ST_INT srcLineNum)
{
#if defined(DEBUG_SISCO)
ST_CHAR fname[SLOG_MAX_FNAME+1];
ST_DOUBLE startTime;
ST_DOUBLE endTime;
ST_DOUBLE elapsedTime;
if (!gs_already_inited) /* Make sure gs is initialized. */
gs_init ();
if (gs_track)
startTime = sGetMsTime ();
gs_mutex_get (&gs_glb_mutex);
if (gs_track)
{
endTime = sGetMsTime ();
elapsedTime = endTime - startTime;
if (elapsedTime > gs_hwMutexTime)
gs_hwMutexTime = elapsedTime;
if (srcFile != NULL)
slogTrimFileName (fname, srcFile);
else
strcpy (fname, "Unknown");
if (gs_debug_sel & GS_LOG_FLOW)
{
GLBSEM_LOG_FLOW2 ("GLBSEM: File %s, Line %d has the mutex",
fname, srcLineNum);
GLBSEM_LOG_CFLOW2 (" took %.3f sec (hw = %.3f)",
elapsedTime/1000, gs_hwMutexTime/1000);
}
++gs_currSemOwnerIndex;
if (gs_currSemOwnerIndex < MAX_SEM_NEST_TRACK)
{
strcpy (gs_currSemOwnerFile[gs_currSemOwnerIndex], fname);
gs_currSemOwnerLine[gs_currSemOwnerIndex] = srcLineNum;
}
else
{
GLBSEM_LOG_CFLOW0 (" Nested too deep to track");
}
}
#else /* Not DEBUG_SISCO */
gs_mutex_get (&gs_glb_mutex);
#endif /* DEBUG_SISCO */
}
/************************************************************************/
/* gs_free_semx */
/*----------------------------------------------------------------------*/
/* Unlock (release ownership) the global SISCO MUTEX semaphore. */
/* This debug version function keeps track of the sem owner stack. */
/* If compiled without DEBUG_SISCO is just falls through to gs_free_sem.*/
/* If compiled with DEBUG_SISCO the gs_track variable need to be set to */
/* value >0 to enable the tracking code. This way logging can be used */
/* by an application without degradation of the MUTEX sem performance. */
/* In addition the gs_debug_sel need to be set to GS_LOG_FLOW to log */
/* the tracking results. */
/* Parameters: */
/* srcFile ptr to source code file name calling this fun */
/* srcLineNum source code line number */
/* Return values: */
/* none */
/* CRITICAL: gs_free_semx must NOT be called from any slog or stime */
/* functions. It calls slog and stime functions which would cause */
/* an infinite loop. Slog and stime must call gs_mutex_free. */
/************************************************************************/
ST_VOID gs_free_semx (SD_CONST ST_CHAR *srcFile, ST_INT srcLineNum)
{
#if defined(DEBUG_SISCO)
ST_CHAR fname[SLOG_MAX_FNAME+1];
ST_INT idx;
if (!gs_already_inited) /* Make sure gs is initialized. */
{
GLBSEM_LOG_ERR0 ("GLBSEM gs_free_semx error: global mutex semaphore not initialized");
return;
}
if (gs_track)
{
if (srcFile != NULL)
slogTrimFileName (fname, srcFile);
else
strcpy (fname, "Unknown");
GLBSEM_LOG_FLOW2 ("GLBSEM: File %s, Line %d freeing the semaphore",
fname, srcLineNum);
idx = gs_currSemOwnerIndex;
--gs_currSemOwnerIndex;
if (gs_currSemOwnerIndex == -1)
{
GLBSEM_LOG_CFLOW0 (" The semaphore should now be free");
}
else if (gs_currSemOwnerIndex >= 0 && gs_currSemOwnerIndex < MAX_SEM_NEST_TRACK)
{
GLBSEM_LOG_CFLOW2 (" File %s, Line %d now has the semaphore",
gs_currSemOwnerFile[gs_currSemOwnerIndex],
gs_currSemOwnerLine[gs_currSemOwnerIndex]);
strcpy (gs_currSemFreeFile[idx], fname);
gs_currSemFreeLine[idx] = srcLineNum;
if (strcmpi (gs_currSemFreeFile[idx], gs_currSemOwnerFile[idx]))
{
GLBSEM_LOG_ERR2 ("Possible problem: %s (%d)", gs_currSemOwnerFile[idx],
gs_currSemOwnerLine[idx]);
}
}
else if (gs_currSemOwnerIndex >= 0 && gs_currSemOwnerIndex >= MAX_SEM_NEST_TRACK)
{
GLBSEM_LOG_CFLOW0 (" Nested too deep to track");
}
else if (gs_currSemOwnerIndex < -1)
{
GLBSEM_LOG_ERR0 ("GLBSEM gs_free_semx error: Sem track index negative");
gs_currSemOwnerIndex = -1;
}
}
#endif /* DEBUG_SISCO */
gs_mutex_free (&gs_glb_mutex);
}
#endif /* defined(S_MT_SUPPORT) */

1064
mmslib/util/glbsem_unix.c Normal file

File diff suppressed because it is too large Load Diff

1139
mmslib/util/glbsem_w32.c Normal file

File diff suppressed because it is too large Load Diff

353
mmslib/util/scl_log.c Normal file
View File

@@ -0,0 +1,353 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 2004-2004 All Rights Reserved */
/* */
/* MODULE NAME : scl_log.c */
/* PRODUCT(S) : MMS-EASE-LITE */
/* */
/* MODULE DESCRIPTION : */
/* Functions to log info parsed from SCL file. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* scl_log_all_data_types */
/* scl_log_all_logical_devices */
/* scl_log_all */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 05/08/07 JRB 02 Fix log message. */
/* 06/10/04 DWL 01 Initial Revision. */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#include "scl.h"
#include "slog.h"
#include "sx_log.h"
#ifdef DEBUG_SISCO
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
#endif
/************************************************************************/
/* scl_log_do */
/************************************************************************/
static ST_VOID scl_log_do (SCL_DO *scl_do)
{
SXLOG_DEC2 ("SCL LOG: <DO name='%s' type='%s'>",
scl_do->name, scl_do->type);
}
/************************************************************************/
/* scl_log_da */
/************************************************************************/
static ST_VOID scl_log_da (SCL_DA *scl_da)
{
ST_CHAR dchg[6];
ST_CHAR qchg[6];
ST_CHAR dupd[6];
SXLOG_DEC8 ("SCL LOG: <DA name='%s' desc='%s' sAddr='%s' bType='%s' valKind='%s' type='%s' count='%u' fc='%s'",
scl_da->name, scl_da->desc, scl_da->sAddr, scl_da->bType,
scl_da->valKind, scl_da->type, scl_da->count, scl_da->fc);
if (scl_da->dchg == SD_TRUE)
strncpy (dchg, "true", sizeof(dchg));
else
strncpy (dchg, "false", sizeof(dchg));
if (scl_da->qchg == SD_TRUE)
strncpy (qchg, "true", sizeof(qchg));
else
strncpy (qchg, "false", sizeof(qchg));
if (scl_da->dupd == SD_TRUE)
strncpy (dupd, "true", sizeof(dupd));
else
strncpy (dupd, "false", sizeof(dupd));
SXLOG_CDEC3 ("SCL LOG: dchg='%s' qchg='%s' dupd='%s'>",
dchg, qchg, dupd);
}
/************************************************************************/
/* scl_log_sdo */
/************************************************************************/
static ST_VOID scl_log_sdo (SCL_DA *scl_da)
{
SXLOG_DEC3 ("SCL LOG: <SDO name='%s' desc='%s' type='%s'>",
scl_da->name, scl_da->desc, scl_da->type);
}
/************************************************************************/
/* scl_log_lntype */
/************************************************************************/
static ST_VOID scl_log_lntype (SCL_LNTYPE *scl_lntype)
{
SCL_DO *scl_do;
SXLOG_DEC2 ("SCL LOG: <LNodeType id='%s' lnClass='%s'>",
scl_lntype->id, scl_lntype->lnClass);
for (scl_do = (SCL_DO *) list_find_last ((DBL_LNK *) scl_lntype->doHead);
scl_do != NULL;
scl_do = (SCL_DO *) list_find_prev ((DBL_LNK *) scl_lntype->doHead, (DBL_LNK *) scl_do))
{
scl_log_do (scl_do);
}
}
/************************************************************************/
/* scl_log_dotype */
/************************************************************************/
static ST_VOID scl_log_dotype (SCL_DOTYPE *scl_dotype)
{
SCL_DA *scl_da;
SXLOG_DEC2 ("SCL LOG: <DOType id='%s' cdc='%s'>",
scl_dotype->id, scl_dotype->cdc);
for (scl_da = (SCL_DA *) list_find_last ((DBL_LNK *) scl_dotype->daHead);
scl_da != NULL;
scl_da = (SCL_DA *) list_find_prev ((DBL_LNK *) scl_dotype->daHead, (DBL_LNK *) scl_da))
{
if (scl_da->objtype == SCL_OBJTYPE_SDO)
scl_log_sdo (scl_da);
else /* Must be SCL_OBJTYPE_DA */
scl_log_da (scl_da);
}
}
/************************************************************************/
/* scl_log_bda */
/************************************************************************/
static ST_VOID scl_log_bda (SCL_BDA *scl_bda)
{
SXLOG_DEC7 ("SCL LOG: <BDA name='%s' desc='%s' sAddr='%s' bType='%s' valKind='%s' type='%s' count='%u'>",
scl_bda->name, scl_bda->desc, scl_bda->sAddr,
scl_bda->bType, scl_bda->valKind, scl_bda->type,
scl_bda->count);
SXLOG_DEC1 ("SCL LOG: <Val='%s'>", scl_bda->Val);
}
/************************************************************************/
/* scl_log_datype */
/************************************************************************/
static ST_VOID scl_log_datype (SCL_DATYPE *scl_datype)
{
SCL_BDA *scl_bda;
SXLOG_DEC1 ("SCL LOG: <DAType id='%s'>",
scl_datype->id);
for (scl_bda = (SCL_BDA *) list_find_last ((DBL_LNK *) scl_datype->bdaHead);
scl_bda != NULL;
scl_bda = (SCL_BDA *) list_find_prev ((DBL_LNK *) scl_datype->bdaHead, (DBL_LNK *) scl_bda))
{
scl_log_bda (scl_bda);
}
}
/************************************************************************/
/* scl_log_enumval */
/************************************************************************/
static ST_VOID scl_log_enumval (SCL_ENUMVAL *scl_enumval)
{
SXLOG_DEC2 ("SCL LOG: <EnumVal ord='%u' EnumVal='%s'>",
scl_enumval->ord, scl_enumval->EnumVal);
}
/************************************************************************/
/* scl_log_enumtype */
/************************************************************************/
static ST_VOID scl_log_enumtype (SCL_ENUMTYPE *scl_enumtype)
{
SCL_ENUMVAL *scl_enumval;
SXLOG_DEC1 ("SCL LOG: <EnumType id='%s'>",
scl_enumtype->id);
for (scl_enumval = (SCL_ENUMVAL *) list_find_last ((DBL_LNK *) scl_enumtype->enumvalHead);
scl_enumval != NULL;
scl_enumval = (SCL_ENUMVAL *) list_find_prev ((DBL_LNK *) scl_enumtype->enumvalHead, (DBL_LNK *) scl_enumval))
{
scl_log_enumval (scl_enumval);
}
}
/************************************************************************/
/* scl_log_all_data_types */
/************************************************************************/
ST_VOID scl_log_all_data_types (SCL_INFO *scl_info)
{
SCL_LNTYPE *scl_lntype;
SCL_DOTYPE *scl_dotype;
SCL_DATYPE *scl_datype;
SCL_ENUMTYPE *scl_enumtype;
/* NOTE: linked list is in reverse order from data in SCL file, */
/* so get off list in reverse order. */
for (scl_lntype = (SCL_LNTYPE *) list_find_last ((DBL_LNK *) scl_info->lnTypeHead);
scl_lntype != NULL;
scl_lntype = (SCL_LNTYPE *) list_find_prev ((DBL_LNK *) scl_info->lnTypeHead, (DBL_LNK *) scl_lntype))
{
scl_log_lntype (scl_lntype);
}
for (scl_dotype = (SCL_DOTYPE *) list_find_last ((DBL_LNK *) scl_info->doTypeHead);
scl_dotype != NULL;
scl_dotype = (SCL_DOTYPE *) list_find_prev ((DBL_LNK *) scl_info->doTypeHead, (DBL_LNK *) scl_dotype))
{
scl_log_dotype (scl_dotype);
}
for (scl_datype = (SCL_DATYPE *) list_find_last ((DBL_LNK *) scl_info->daTypeHead);
scl_datype != NULL;
scl_datype = (SCL_DATYPE *) list_find_prev ((DBL_LNK *) scl_info->daTypeHead, (DBL_LNK *) scl_datype))
{
scl_log_datype (scl_datype);
}
for (scl_enumtype = (SCL_ENUMTYPE *) list_find_last ((DBL_LNK *) scl_info->enumTypeHead);
scl_enumtype != NULL;
scl_enumtype = (SCL_ENUMTYPE *) list_find_prev ((DBL_LNK *) scl_info->enumTypeHead, (DBL_LNK *) scl_enumtype))
{
scl_log_enumtype (scl_enumtype);
}
}
/************************************************************************/
/* scl_log_fcda */
/************************************************************************/
static ST_VOID scl_log_fcda (SCL_FCDA *scl_fcda)
{
SXLOG_DEC7 ("SCL LOG: <FCDA ldInst='%s' prefix='%s' lnInst='%s' lnClass='%s' doName='%s' daName='%s' fc='%s'>",
scl_fcda->ldInst, scl_fcda->prefix, scl_fcda->lnInst,
scl_fcda->lnClass, scl_fcda->doName, scl_fcda->daName,
scl_fcda->fc);
}
/************************************************************************/
/* scl_log_dataset */
/************************************************************************/
static ST_VOID scl_log_dataset (SCL_DATASET *scl_dataset)
{
SCL_FCDA *scl_fcda;
SXLOG_DEC2 ("SCL LOG: <Dataset name='%s' desc='%s'>",
scl_dataset->name, scl_dataset->desc);
for (scl_fcda = (SCL_FCDA *) list_find_last ((DBL_LNK *) scl_dataset->fcdaHead);
scl_fcda != NULL;
scl_fcda = (SCL_FCDA *) list_find_prev ((DBL_LNK *) scl_dataset->fcdaHead, (DBL_LNK *) scl_fcda))
{
scl_log_fcda (scl_fcda);
}
}
/************************************************************************/
/* scl_log_rcb */
/************************************************************************/
static ST_VOID scl_log_rcb (SCL_RCB *scl_rcb)
{
ST_CHAR buffered[6];
if (scl_rcb->buffered == SD_TRUE)
strncpy (buffered, "true", sizeof (buffered));
else
strncpy (buffered, "false", sizeof (buffered));
SXLOG_DEC8 ("SCL LOG: <ReportControl name='%s' desc='%s' datSet='%s' intgPd='%u' rptID='%s' confRev='%u' buffered='%s' bufTime='%u'",
scl_rcb->name, scl_rcb->desc, scl_rcb->datSet,
scl_rcb->intgPd, scl_rcb->rptID, scl_rcb->confRev,
buffered, scl_rcb->bufTime);
/* These are bitstrings. Just log as hex. */
SXLOG_CDEC3 ("SCL LOG: TrgOps=0x%02X, OptFlds=0x%02X%02X",
(ST_UINT) scl_rcb->TrgOps [0],
(ST_UINT) scl_rcb->OptFlds[0],
(ST_UINT) scl_rcb->OptFlds[1] );
}
/************************************************************************/
/* scl_log_ln */
/************************************************************************/
static ST_VOID scl_log_ln (SCL_LN *scl_ln)
{
SCL_DATASET *scl_dataset;
SCL_RCB *scl_rcb;
SXLOG_DEC5 ("SCL LOG: <LNode desc='%s' lnType='%s' lnClass='%s' inst='%s' prefix='%s'>",
scl_ln->desc, scl_ln->lnType, scl_ln->lnClass,
scl_ln->inst, scl_ln->prefix);
/* Log Datasets */
for (scl_dataset = (SCL_DATASET *) list_find_last ((DBL_LNK *) scl_ln->datasetHead);
scl_dataset != NULL;
scl_dataset = (SCL_DATASET *) list_find_prev ((DBL_LNK *) scl_ln->datasetHead, (DBL_LNK *) scl_dataset))
{
scl_log_dataset (scl_dataset);
}
/* Log RCBs */
for (scl_rcb = (SCL_RCB *) list_find_last ((DBL_LNK *) scl_ln->rcbHead);
scl_rcb != NULL;
scl_rcb = (SCL_RCB *) list_find_prev ((DBL_LNK *) scl_ln->rcbHead, (DBL_LNK *) scl_rcb))
{
scl_log_rcb (scl_rcb);
}
}
/************************************************************************/
/* scl_log_ld */
/************************************************************************/
static ST_VOID scl_log_ld (
SCL_INFO *scl_info, /* main struct where all SCL info stored*/
SCL_LD *scl_ld)
{
SCL_LN *scl_ln;
SXLOG_DEC2 ("SCL LOG: <LDevice desc='%s' inst='%s'>",
scl_ld->desc, scl_ld->inst);
/* Log Logical nodes */
/* NOTE: linked lists are in reverse order from data in SCL file, */
/* so get off list in reverse order. */
for (scl_ln = (SCL_LN *) list_find_last ((DBL_LNK *) scl_ld->lnHead);
scl_ln != NULL;
scl_ln = (SCL_LN *) list_find_prev ((DBL_LNK *) scl_ld->lnHead, (DBL_LNK *) scl_ln))
{
scl_log_ln (scl_ln);
}
}
/************************************************************************/
/* scl_log_all_logical_devices */
/* Log all Logical Devices from SCL info saved in "scl_info". */
/* RETURNS: SD_SUCCESS or error code */
/************************************************************************/
ST_VOID scl_log_all_logical_devices (SCL_INFO *scl_info)
{
SCL_LD *scl_ld;
/* NOTE: linked list is in reverse order from data in SCL file, */
/* so get off list in reverse order. */
for (scl_ld = (SCL_LD *) list_find_last ((DBL_LNK *) scl_info->ldHead);
scl_ld != NULL;
scl_ld = (SCL_LD *) list_find_prev ((DBL_LNK *) scl_info->ldHead, (DBL_LNK *) scl_ld))
{
scl_log_ld (scl_info, scl_ld);
}
}
/************************************************************************/
/* scl_log_all */
/* Log everything from SCL info saved in "scl_info". */
/************************************************************************/
ST_VOID scl_log_all (SCL_INFO *scl_info)
{
scl_log_all_logical_devices (scl_info);
scl_log_all_data_types (scl_info);
}

2507
mmslib/util/sclparse.c Normal file

File diff suppressed because it is too large Load Diff

737
mmslib/util/sclstore.c Normal file
View File

@@ -0,0 +1,737 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 2004-2006 All Rights Reserved */
/* */
/* MODULE NAME : sclstore.c */
/* PRODUCT(S) : MMS-EASE-LITE */
/* */
/* MODULE DESCRIPTION : */
/* Functions to store information parsed from SCL file. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* scl_lntype_create */
/* scl_lntype_add_do */
/* scl_dotype_create */
/* scl_dotype_add_da */
/* scl_dotype_add_sdo */
/* scl_datype_create */
/* scl_datype_add_bda */
/* scl_enumtype_create */
/* scl_enumtype_add_enumval */
/* scl_fcda_add */
/* scl_dai_add */
/* scl_dataset_add */
/* scl_rcb_add */
/* scl_lcb_add */
/* scl_gcb_add */
/* scl_ln_add */
/* scl_ld_create */
/* scl_info_destroy */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 04/23/08 JRB 11 Add scl_sgcb_add. */
/* 07/26/06 JRB 10 Add scl_subnet_add, scl_cap_add, scl_gse_add,*/
/* scl_smv_add. */
/* 04/04/06 JRB 09 Add scl_svcb_add: alloc SCL_SVCB & add to list.*/
/* 03/15/06 JRB 08 Simplify functions: Do not copy data. */
/* Most functions take only (SCL_INFO *) arg & */
/* just alloc struct and add to linked list. */
/* Del scl_dotype_add_da_val, */
/* scl_datype_add_bda_val, scl_header_save. */
/* 01/30/06 GLB 07 Integrated porting changes for VMS */
/* 07/25/05 JRB 06 If nameStructure!=IEDName, ignore it and */
/* assume nameStructure=IEDName anyway. */
/* 06/29/05 CRM 05 Add scl_info_destroy. */
/* 06/24/05 JRB 04 Chg "ord" from unsigned to signed value. */
/* 02/15/05 JRB 03 Chg scl_ld_create to generate scl_ld->domName.*/
/* Chg scl_fcda_add to generate scl_fcda->domName.*/
/* Chg scl_ln_add to generate scl_ln->varName. */
/* Add scl_header_save. */
/* 07/19/04 JRB 02 Add scl_lcb_add, scl_gcb_add. */
/* 06/10/04 JRB 01 Initial Revision. */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#include "scl.h"
#include "sx_log.h"
#include "str_util.h"
#ifdef DEBUG_SISCO
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
#endif
/* NOTE:
* Functions with "scl_" prefix used while parsing SCL file to
* store data in linked lists.
* Functions with "scl2_" prefix (see sclproc.c) used to read info from
* linked lists and create MMS objects (Domains, variables, NVLs, etc.).
*/
/************************************************************************/
/* scl_lntype_create */
/* Begin creation of a Logical Node Type (LNodeType). */
/* RETURNS: SD_SUCCESS or error code */
/************************************************************************/
SCL_LNTYPE *scl_lntype_create (
SCL_INFO *scl_info) /* struct to store all SCL info */
{
SCL_LNTYPE *scl_lntype;
scl_lntype = (SCL_LNTYPE *) chk_calloc (1, sizeof (SCL_LNTYPE));
/* Add LNType to front of LNType List. */
list_add_first (&scl_info->lnTypeHead, scl_lntype);
return (scl_lntype);
}
/************************************************************************/
/* scl_lntype_add_do */
/* Add a Data Object (DO) to a Logical Node Type (LNodeType). */
/* Adds to lntype created by most recent call to "scl_lntype_create". */
/* RETURNS: SD_SUCCESS or error code */
/************************************************************************/
SCL_DO *scl_lntype_add_do (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_DO *scl_do = NULL; /* assume failure */
/* All higher level linked lists must be initialized. */
if (scl_info->lnTypeHead)
{
scl_do = (SCL_DO *) chk_calloc (1, sizeof (SCL_DO));
/* Add DO to front of DO List in first entry of LNType list */
list_add_first (&scl_info->lnTypeHead->doHead, scl_do);
}
else
SXLOG_ERR0 ("Cannot add DO to NULL LNTYPE");
return (scl_do);
}
/************************************************************************/
/* scl_dotype_create */
/* Begin creation of a Data Object Type (DOType). */
/* RETURNS: SD_SUCCESS or error code */
/************************************************************************/
SCL_DOTYPE *scl_dotype_create (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_DOTYPE *scl_dotype;
scl_dotype = (SCL_DOTYPE *) chk_calloc (1, sizeof (SCL_DOTYPE));
/* Add DOType to front of DOType List. */
list_add_first (&scl_info->doTypeHead, scl_dotype);
return (scl_dotype);
}
/************************************************************************/
/* scl_dotype_add_da */
/* Add a Data Attribute (DA) to a Data Object Type (DOType). */
/* RETURNS: SD_SUCCESS or error code */
/************************************************************************/
SCL_DA *scl_dotype_add_da (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_DA *scl_da = NULL; /* assume failure */
/* All higher level linked lists must be initialized. */
if (scl_info->doTypeHead)
{
scl_da = (SCL_DA *) chk_calloc (1, sizeof (SCL_DA));
/* CRITICAL: DA and SDO use same struct, "objtype" tells which one it is.*/
scl_da->objtype = SCL_OBJTYPE_DA;
/* Add DA to front of DA List in first entry of DOType list */
list_add_first (&scl_info->doTypeHead->daHead, scl_da);
}
else
SXLOG_ERR0 ("Cannot add DA to NULL DO");
return (scl_da);
}
/************************************************************************/
/* scl_dotype_add_sdo */
/* Add a (SDO) to a Data Object Type (DOType). */
/* RETURNS: SD_SUCCESS or error code */
/************************************************************************/
SCL_DA *scl_dotype_add_sdo (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_DA *scl_da = NULL; /* assume failure */
/* All higher level linked lists must be initialized. */
if (scl_info->doTypeHead)
{
scl_da = (SCL_DA *) chk_calloc (1, sizeof (SCL_DA));
/* CRITICAL: DA and SDO use same struct, "objtype" tells which one it is.
* NOTE: Because this is SDO, the sAddr, bType, and valKind members of
* the scl_da structure are NOT used.
*/
scl_da->objtype = SCL_OBJTYPE_SDO;
/* Add DA to front of DA List in first entry of DOType list */
list_add_first (&scl_info->doTypeHead->daHead, scl_da);
}
else
SXLOG_ERR0 ("Cannot add SDO to NULL DO");
return (scl_da);
}
/************************************************************************/
/* scl_datype_create */
/* Begin creation of a Data Attribute Type (DAType). */
/* RETURNS: SD_SUCCESS or error code */
/************************************************************************/
SCL_DATYPE *scl_datype_create (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_DATYPE *scl_datype;
scl_datype = (SCL_DATYPE *) chk_calloc (1, sizeof (SCL_DATYPE));
/* Add DAType to front of DAType List. */
list_add_first (&scl_info->daTypeHead, scl_datype);
return (scl_datype);
}
/************************************************************************/
/* scl_datype_add_bda */
/* Add a Basic Data Attribute (BDA) to a Data Attribute Type (DAType). */
/* RETURNS: SD_SUCCESS or error code */
/************************************************************************/
SCL_BDA *scl_datype_add_bda (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_BDA *scl_bda = NULL; /* assume failure */
/* All higher level linked lists must be initialized. */
if (scl_info->daTypeHead)
{
scl_bda = (SCL_BDA *) chk_calloc (1, sizeof (SCL_BDA));
/* Add BDA to front of BDA List in first entry of DAType list */
list_add_first (&scl_info->daTypeHead->bdaHead, scl_bda);
}
else
SXLOG_ERR0 ("Cannot add BDA to NULL DATYPE");
return (scl_bda);
}
/************************************************************************/
/* scl_enumtype_create */
/* Begin creation of an EnumType. */
/* RETURNS: SD_SUCCESS or error code */
/************************************************************************/
SCL_ENUMTYPE *scl_enumtype_create (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_ENUMTYPE *scl_enumtype;
scl_enumtype = (SCL_ENUMTYPE *) chk_calloc (1, sizeof (SCL_ENUMTYPE));
/* Add EnumType to front of EnumType List. */
list_add_first (&scl_info->enumTypeHead, scl_enumtype);
return (scl_enumtype);
}
/************************************************************************/
/* scl_enumtype_add_enumval */
/* Add an EnumVal to an EnumType. */
/* Add to EnumType created by most recent call to scl_enumtype_create. */
/* RETURNS: SD_SUCCESS or error code */
/************************************************************************/
SCL_ENUMVAL *scl_enumtype_add_enumval (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_ENUMVAL *scl_enumval = NULL; /* assume failure */
/* All higher level linked lists must be initialized. */
if (scl_info->enumTypeHead)
{
scl_enumval = (SCL_ENUMVAL *) chk_calloc (1, sizeof (SCL_ENUMVAL));
/* Add EnumVal to front of EnumVal List in first entry of EnumType list */
list_add_first (&scl_info->enumTypeHead->enumvalHead, scl_enumval);
}
else
SXLOG_ERR0 ("Cannot add ENUMVAL to NULL ENUMTYPE");
return (scl_enumval);
}
/************************************************************************/
/* scl_fcda_add */
/* Allocates a SCL_FCDA struct */
/* and adds it to the linked list "fcdaHead" in SCL_DATASET. */
/************************************************************************/
SCL_FCDA *scl_fcda_add (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_FCDA *scl_fcda = NULL; /* assume failure */
/* All higher level linked lists must be initialized. */
if (scl_info->ldHead
&& scl_info->ldHead->lnHead
&& scl_info->ldHead->lnHead->datasetHead)
{
scl_fcda = (SCL_FCDA *) chk_calloc (1, sizeof (SCL_FCDA));
/* Add FCDA to front of FCDA List. */
list_add_first (&scl_info->ldHead->lnHead->datasetHead->fcdaHead, scl_fcda);
}
else
SXLOG_ERR0 ("Cannot add FCDA to NULL DATASET");
return (scl_fcda);
}
/************************************************************************/
/* scl_dai_add */
/* Allocates a SCL_DAI struct */
/* and adds it to the linked list "daiHead" in SCL_LN. */
/************************************************************************/
SCL_DAI *scl_dai_add (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_DAI *scl_dai = NULL; /* assume failure */
/* All higher level linked lists must be initialized. */
if (scl_info->ldHead
&& scl_info->ldHead->lnHead)
{
scl_dai = (SCL_DAI *) chk_calloc (1, sizeof (SCL_DAI));
/* Add DAI to front of DAI List. */
list_add_first (&scl_info->ldHead->lnHead->daiHead, scl_dai);
}
else
SXLOG_ERR0 ("Cannot add DAI to NULL LN");
return (scl_dai);
}
/************************************************************************/
/* scl_dataset_add */
/* Allocates a SCL_DATASET struct */
/* and adds it to the linked list "datasetHead" in SCL_LN. */
/************************************************************************/
SCL_DATASET *scl_dataset_add (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
/* TRUNCATED if longer than buffer */
{
SCL_DATASET *scl_dataset = NULL; /* assume failure */
/* All higher level linked lists must be initialized. */
if (scl_info->ldHead
&& scl_info->ldHead->lnHead)
{
scl_dataset = (SCL_DATASET *) chk_calloc (1, sizeof (SCL_DATASET));
/* Add DATASET to front of DATASET List. */
list_add_first (&scl_info->ldHead->lnHead->datasetHead, scl_dataset);
}
else
SXLOG_ERR0 ("Cannot add DATASET to NULL LN");
return (scl_dataset);
}
/************************************************************************/
/* scl_rcb_add */
/* Alloc & add SCL_RCB struct to the linked list "rcbHead" in SCL_LN. */
/* NOTE: struct is not filled in yet. */
/* NOTE: the RptEnabled element of the SCL file is ignored. SISCO software*/
/* does not need to know which clients may access the RCB. */
/************************************************************************/
SCL_RCB *scl_rcb_add (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_RCB *scl_rcb = NULL;
/* All higher level linked lists must be initialized. */
if (scl_info->ldHead
&& scl_info->ldHead->lnHead)
{
scl_rcb = (SCL_RCB *) chk_calloc (1, sizeof (SCL_RCB));
/* Add RCB to front of RCB List. */
list_add_first (&scl_info->ldHead->lnHead->rcbHead, scl_rcb);
}
else
SXLOG_ERR0 ("Cannot add RCB to NULL LN");
return (scl_rcb);
}
/************************************************************************/
/* scl_lcb_add */
/* Alloc & add a SCL_LCB struct to the linked list "lcbHead" in SCL_LN. */
/* NOTE: struct is not filled in yet. */
/************************************************************************/
SCL_LCB *scl_lcb_add (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_LCB *scl_lcb = NULL;
/* All higher level linked lists must be initialized. */
if (scl_info->ldHead
&& scl_info->ldHead->lnHead)
{
scl_lcb = (SCL_LCB *) chk_calloc (1, sizeof (SCL_LCB));
/* Add LCB to front of LCB List. */
list_add_first (&scl_info->ldHead->lnHead->lcbHead, scl_lcb);
}
else
SXLOG_ERR0 ("Cannot add LCB to NULL LN");
return (scl_lcb);
}
/************************************************************************/
/* scl_gcb_add */
/* Add a GOOSE Control Block (GCB). */
/* Allocates a SCL_GCB struct */
/* and adds it to the linked list "gcbHead" in SCL_LN. */
/* NOTE: The SCL file may also contain one or more "IEDName" elements to*/
/* indicate IEDs that should subscribe for GOOSE data. We have no */
/* way to use this information, so it is ignored. */
/************************************************************************/
SCL_GCB *scl_gcb_add (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_GCB *scl_gcb = NULL; /* assume failure */
/* All higher level linked lists must be initialized. */
if (scl_info->ldHead
&& scl_info->ldHead->lnHead)
{
scl_gcb = (SCL_GCB *) chk_calloc (1, sizeof (SCL_GCB));
/* Add GCB to front of GCB List. */
list_add_first (&scl_info->ldHead->lnHead->gcbHead, scl_gcb);
}
else
SXLOG_ERR0 ("Cannot add GCB (GOOSE Control Block) to NULL LN");
return (scl_gcb);
}
/************************************************************************/
/* scl_sgcb_add */
/* Add a Setting Group Control Block (SGCB). */
/* Allocates a SCL_SGCB struct, stores ptr in "sgcb" in SCL_LN. */
/************************************************************************/
SCL_SGCB *scl_sgcb_add (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_SGCB *scl_sgcb = NULL; /* assume failure */
/* All higher level linked lists must be initialized. */
if (scl_info->ldHead
&& scl_info->ldHead->lnHead)
{
/* Only one SGCB allowed. Make sure not already set. */
if (scl_info->ldHead->lnHead->sgcb != NULL)
{
SXLOG_ERR0 ("Duplicate SGCB (Setting Group Control Block) not allowed");
return (NULL);
}
else
scl_info->ldHead->lnHead->sgcb = scl_sgcb = (SCL_SGCB *) chk_calloc (1, sizeof (SCL_SGCB));
}
else
SXLOG_ERR0 ("Cannot add SGCB (Setting Group Control Block) to NULL LN");
return (scl_sgcb);
}
/************************************************************************/
/* scl_svcb_add */
/* Alloc & add SCL_SVCB struct to the linked list "svcbHead" in SCL_LN. */
/* NOTE: struct is not filled in yet. */
/************************************************************************/
SCL_SVCB *scl_svcb_add (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_SVCB *scl_svcb = NULL; /* assume failure */
/* All higher level linked lists must be initialized. */
if (scl_info->ldHead
&& scl_info->ldHead->lnHead)
{
scl_svcb = (SCL_SVCB *) chk_calloc (1, sizeof(SCL_SVCB));
/* Add to front of list. */
list_add_first (&scl_info->ldHead->lnHead->svcbHead, scl_svcb);
}
else
SXLOG_ERR0 ("Cannot add SVCB to NULL LN");
return (scl_svcb);
}
/************************************************************************/
/* scl_ln_add */
/* Allocates a SCL_LN struct */
/* and adds it to the linked list "lnHead" in SCL_LD. */
/************************************************************************/
SCL_LN *scl_ln_add (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_LN *scl_ln = NULL; /* assume failure */
/* All higher level linked lists must be initialized. */
if (scl_info->ldHead)
{
scl_ln = (SCL_LN *) chk_calloc (1, sizeof (SCL_LN));
/* Add LN to front of LN List. */
list_add_first (&scl_info->ldHead->lnHead, scl_ln);
}
else
SXLOG_ERR0 ("Cannot add LN to NULL LD");
return (scl_ln);
}
/************************************************************************/
/* scl_ld_create */
/* Allocates SCL_LD struct */
/* and adds it to the linked list "ldHead" in SCL_INFO. */
/************************************************************************/
SCL_LD *scl_ld_create (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_LD *scl_ld = NULL; /* assume failure */
scl_ld = (SCL_LD *) chk_calloc (1, sizeof (SCL_LD));
/* Add LD to front of LD List. */
list_add_first (&scl_info->ldHead, scl_ld);
return (scl_ld);
}
/************************************************************************/
/* scl_subnet_add */
/* Allocates SCL_SUBNET struct */
/* and adds it to the linked list "subnetHead" in SCL_INFO. */
/************************************************************************/
SCL_SUBNET *scl_subnet_add (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_SUBNET *scl_subnet = NULL; /* assume failure */
scl_subnet = (SCL_SUBNET *) chk_calloc (1, sizeof (SCL_SUBNET));
/* Add to front of list. */
list_add_first (&scl_info->subnetHead, scl_subnet);
return (scl_subnet);
}
/************************************************************************/
/* scl_cap_add */
/* Allocates a SCL_CAP struct */
/* and adds it to the linked list "capHead" in SCL_SUBNET. */
/************************************************************************/
SCL_CAP *scl_cap_add (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_CAP *scl_cap = NULL; /* assume failure */
/* All higher level linked lists must be initialized. */
if (scl_info->subnetHead)
{
scl_cap = (SCL_CAP *) chk_calloc (1, sizeof (SCL_CAP));
/* Add to front of list. */
list_add_first (&scl_info->subnetHead->capHead, scl_cap);
}
else
SXLOG_ERR0 ("Cannot add CAP to NULL SUBNET");
return (scl_cap);
}
/************************************************************************/
/* scl_gse_add */
/* Allocates a SCL_GSE struct */
/* and adds it to the linked list "gseHead" in SCL_CAP. */
/************************************************************************/
SCL_GSE *scl_gse_add (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_GSE *scl_gse = NULL; /* assume failure */
/* All higher level linked lists must be initialized. */
if (scl_info->subnetHead->capHead)
{
scl_gse = (SCL_GSE *) chk_calloc (1, sizeof (SCL_GSE));
/* Add to front of list. */
list_add_first (&scl_info->subnetHead->capHead->gseHead, scl_gse);
}
else
SXLOG_ERR0 ("Cannot add GSE to NULL CAP");
return (scl_gse);
}
/************************************************************************/
/* scl_smv_add */
/* Allocates a SCL_SMV struct */
/* and adds it to the linked list "smvHead" in SCL_CAP. */
/************************************************************************/
SCL_SMV *scl_smv_add (
SCL_INFO *scl_info) /* main struct where all SCL info stored*/
{
SCL_SMV *scl_smv = NULL; /* assume failure */
/* All higher level linked lists must be initialized. */
if (scl_info->subnetHead->capHead)
{
scl_smv = (SCL_SMV *) chk_calloc (1, sizeof (SCL_SMV));
/* Add to front of list. */
list_add_first (&scl_info->subnetHead->capHead->smvHead, scl_smv);
}
else
SXLOG_ERR0 ("Cannot add SMV to NULL CAP");
return (scl_smv);
}
/************************************************************************/
/* scl_info_destroy */
/* Destroy all info stored in the SCL_INFO structure by "scl_parse". */
/* NOTE: most buffers were allocated by functions in this module. The */
/* elements "Val" and "desc" in several structures were allocated */
/* by functions in "sclparse.c". */
/************************************************************************/
ST_VOID scl_info_destroy (SCL_INFO *scl_info)
{
SCL_LNTYPE *lnType;
SCL_DO *scl_do;
SCL_LD *scl_ld;
SCL_LN *scl_ln;
SCL_RCB *scl_rcb;
SCL_LCB *scl_lcb;
SCL_GCB *scl_gcb;
SCL_SVCB *scl_svcb;
SCL_DAI *scl_dai;
SCL_DATASET *scl_dataset;
SCL_FCDA *scl_fcda;
SCL_DATYPE * scl_daType;
SCL_BDA *scl_bda;
SCL_ENUMTYPE *scl_enum;
SCL_ENUMVAL *scl_enumval;
SCL_DOTYPE *scl_doType;
SCL_DA *scl_da;
SCL_SUBNET *scl_subnet;
SCL_CAP *scl_cap;
SCL_GSE *scl_gse;
SCL_SMV *scl_smv;
while ((scl_subnet = (SCL_SUBNET *) list_get_first(&scl_info->subnetHead)) != NULL)
{
while ((scl_cap = (SCL_CAP *) list_get_first(&scl_subnet->capHead)) != NULL)
{
while ((scl_gse = (SCL_GSE *) list_get_first(&scl_cap->gseHead)) != NULL)
{
chk_free(scl_gse);
}
while ((scl_smv = (SCL_SMV *) list_get_first(&scl_cap->smvHead)) != NULL)
{
chk_free(scl_smv);
}
if (scl_cap->desc)
chk_free (scl_cap->desc);
chk_free (scl_cap);
}
if (scl_subnet->desc)
chk_free (scl_subnet->desc);
chk_free (scl_subnet);
}
while ((scl_daType = (SCL_DATYPE *) list_get_first (&scl_info->daTypeHead)) != NULL)
{
while ((scl_bda = (SCL_BDA *) list_get_first (&scl_daType->bdaHead)) != NULL)
{
if (scl_bda->desc)
chk_free (scl_bda->desc);
if (scl_bda->Val)
chk_free (scl_bda->Val);
chk_free (scl_bda);
}
chk_free (scl_daType);
}
while ((lnType = (SCL_LNTYPE *) list_get_first (&scl_info->lnTypeHead)) != NULL)
{
while ((scl_do = (SCL_DO *) list_get_first (&lnType->doHead)) != NULL)
{
chk_free (scl_do);
}
chk_free (lnType);
}
while ((scl_doType = (SCL_DOTYPE *) list_get_first (&scl_info->doTypeHead)) != NULL)
{
while ((scl_da = (SCL_DA *) list_get_first (&scl_doType->daHead)) != NULL)
{
if (scl_da->desc)
chk_free (scl_da->desc);
if (scl_da->Val)
chk_free (scl_da->Val);
chk_free (scl_da);
}
chk_free (scl_doType);
}
while ((scl_enum = (SCL_ENUMTYPE *) list_get_first (&scl_info->enumTypeHead)) != NULL)
{
while ((scl_enumval = (SCL_ENUMVAL *) list_get_first (&scl_enum->enumvalHead)) != NULL)
{
chk_free (scl_enumval);
}
chk_free (scl_enum);
}
while ((scl_ld = (SCL_LD *) list_get_first (&scl_info->ldHead)) != NULL)
{
while ((scl_ln = (SCL_LN *) list_get_first (&scl_ld->lnHead)) != NULL)
{
while ((scl_dai = (SCL_DAI *) list_get_first (&scl_ln->daiHead)) != NULL)
{
if (scl_dai->Val)
chk_free (scl_dai->Val);
chk_free (scl_dai);
}
while ((scl_dataset = (SCL_DATASET *) list_get_first (&scl_ln->datasetHead)) != NULL)
{
while ((scl_fcda = (SCL_FCDA *) list_get_first (&scl_dataset->fcdaHead)) != NULL)
{
chk_free (scl_fcda);
}
if (scl_dataset->desc)
chk_free (scl_dataset->desc);
chk_free (scl_dataset);
}
while ((scl_rcb = (SCL_RCB *) list_get_first (&scl_ln->rcbHead)) != NULL)
{
if (scl_rcb->desc)
chk_free (scl_rcb->desc);
chk_free (scl_rcb);
}
while ((scl_lcb = (SCL_LCB *) list_get_first (&scl_ln->lcbHead)) != NULL)
{
if (scl_lcb->desc)
chk_free (scl_lcb->desc);
chk_free (scl_lcb);
}
while ((scl_gcb = (SCL_GCB *) list_get_first (&scl_ln->gcbHead)) != NULL)
{
if (scl_gcb->desc)
chk_free (scl_gcb->desc);
chk_free (scl_gcb);
}
while ((scl_svcb = (SCL_SVCB *) list_get_first (&scl_ln->svcbHead)) != NULL)
{
if (scl_svcb->desc)
chk_free (scl_svcb->desc);
chk_free (scl_svcb);
}
/* Only one SGCB allowed (no linked list) */
if (scl_ln->sgcb)
{
if (scl_ln->sgcb->desc)
chk_free (scl_ln->sgcb->desc);
chk_free (scl_ln->sgcb);
}
if (scl_ln->desc)
chk_free (scl_ln->desc);
chk_free (scl_ln);
}
if (scl_ld->desc)
chk_free (scl_ld->desc);
chk_free (scl_ld);
}
}

3815
mmslib/util/stdtime.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,194 @@
/*****************************************************************************/
/* SISCO SOFTWARE MODULE HEADER **********************************************/
/*****************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 2006 All Rights Reserved */
/* */
/* MODULE NAME : stdtime_mms_btime.c */
/* PRODUCT(S) : Standard Time Management Library */
/* */
/* MODULE DESCRIPTION: */
/* Support for MMS Btime4, BTime6 and BTOD conversions to/from STDTIME */
/* */
/* MODIFICATION LOG: */
/* Date Who Rev Comments */
/* -------- --- --- ----------------------------------------------------- */
/* 02/20/08 JRB 02 Make STDTIME same as FILETIME (simplifies a lot). */
/* Move T84_* defines to header file. */
/* Del TimeOfDay4, Btod, and StdTimeFields functions. */
/* 10/05/06 RLH 01 Created */
/*****************************************************************************/
#include "stdtime.h"
#include "stdtime_mms_btime.h"
/*** MmsTimeOfDay6 initialization functions ***************************/
STDTIME_MMS_TIMEOFDAY6 StdTimeApiZeroMmsTimeOfDay6 ()
{
STDTIME_MMS_TIMEOFDAY6 zero = {0};
return zero;
} /* StdTimeApiZeroMmsTimeOfDay6 */
/*** MmsTimeOfDay6Ex functions ***********************************************/
/*-***************************************************************************/
/* StdTimeToMmsTimeOfDay6Ex */
/* convert: StdTime struct to MMS_TIMEOFDAY6 and extra fields */
/* method: subtract 1984-01-01 from stdTime to form delta */
/*****************************************************************************/
STDTIME_RC StdTimeToMmsTimeOfDay6Ex (
const STDTIME * /*I*/ pStdTime,
STDTIME_MMS_TIMEOFDAY6 * /*O*/ pMmsTimeOfDay6,
int32_t * /*O*/ pUsec,
int32_t * /*O*/ pNsec)
{
/* pre-calculated STDTIME value of 1984-01-01 00:00:00.0000000 */
STDTIME t84; /* initialized below */
STDTIME_DELTA mms;
STDTIME_ENUM_FUNC (StdTimeToMmsTimeOfDay6Ex)
if (pStdTime->dwHighDateTime < T84_HIGHDATETIME ||
(pStdTime->dwHighDateTime == T84_HIGHDATETIME &&
pStdTime->dwLowDateTime < T84_LOWDATETIME))
{
STDTIME_RET_EC (MMS_year_LT_1984);
}
t84.dwHighDateTime = T84_HIGHDATETIME; /* initialize */
t84.dwLowDateTime = T84_LOWDATETIME;
if (pMmsTimeOfDay6 == NULL)
{
STDTIME_RET_EC (null_argument);
}
*pMmsTimeOfDay6 = StdTimeApiZeroMmsTimeOfDay6();
/* form difference between supplied date and 1984 */
if STDTIME_IFNOT (StdTime_GetDelta (pStdTime, &t84, &mms))
{
STDTIME_RET_RC;
}
pMmsTimeOfDay6->day = mms.day;
pMmsTimeOfDay6->ms =
(mms.hour * 60 * 60 * 1000) +
(mms.min * 60 * 1000) +
(mms.sec * 1000) + mms.msec;
if (pUsec != NULL)
{
*pUsec = mms.usec;
}
if (pNsec != NULL)
{
*pNsec = mms.nsec;
}
STDTIME_RET_OK;
} /* StdTimeToMmsTimeOfDay6Ex */
/*-***************************************************************************/
/* MmsTimeOfDay6ExToStdTime */
/* convert: MMS_TIMEOFDAY6 and extra fields to StdTime struct */
/* method: add MMS days and msec to base value of 1984-01-01 */
/*****************************************************************************/
STDTIME_RC MmsTimeOfDay6ExToStdTime (
const STDTIME_MMS_TIMEOFDAY6 * /*I*/ pMmsTimeOfDay6,
int32_t /*I*/ nUsec,
int32_t /*I*/ nNsec,
STDTIME * /*O*/ pStdTime)
{
/* pre-calculated STDTIME value of 1984-01-01 00:00:00.0000000 */
STDTIME t84; /* initialized below */
STDTIME_DELTA mms = {0};
STDTIME_ENUM_FUNC (MmsTimeOfDay6ExToStdTime)
t84.dwHighDateTime = T84_HIGHDATETIME; /* initialize */
t84.dwLowDateTime = T84_LOWDATETIME;
if (pStdTime == NULL)
{
STDTIME_RET_EC (null_argument);
}
*pStdTime = ZeroStdTime ();
if (pMmsTimeOfDay6 == NULL)
{
STDTIME_RET_EC (null_argument);
}
*pStdTime = ZeroStdTime();
/* create delta from 1984-01-01 */
mms.day = pMmsTimeOfDay6->day;
mms.msec = pMmsTimeOfDay6->ms;
mms.usec = nUsec;
mms.nsec = nNsec;
/* add mms displacement to mms epoch date of Jan 1 1984 */
if STDTIME_IFNOT (StdTime_AddDelta (&t84, &mms))
{
STDTIME_RET_RC;
}
*pStdTime = t84;
STDTIME_RET_OK;
} /* MmsTimeOfDay6ExToStdTime */
/*** MmsTimeOfDay6 functions *************************************************/
/*-***************************************************************************/
/* StdTimeToMmsTimeOfDay6 */
/* convert: StdTime struct to MMS_TIMEOFDAY6 (without extra fields) */
/*****************************************************************************/
STDTIME_RC StdTimeToMmsTimeOfDay6 (
const STDTIME * /*I*/ pStdTime,
STDTIME_MMS_TIMEOFDAY6 * /*O*/ pMmsTimeOfDay6)
{
STDTIME_ENUM_FUNC (StdTimeToMmsTimeOfDay6)
STDTIME_RET (StdTimeToMmsTimeOfDay6Ex (pStdTime, pMmsTimeOfDay6, NULL, NULL));
} /* StdTimeToMmsTimeOfDay6 */
/*-***************************************************************************/
/* MmsTimeOfDay6ToStdTime */
/* convert: MMS_TIMEOFDAY6 (without extra fields) to StdTime struct */
/*****************************************************************************/
STDTIME_RC MmsTimeOfDay6ToStdTime (
const STDTIME_MMS_TIMEOFDAY6 * /*I*/ pMmsTimeOfDay6,
STDTIME * /*O*/ pStdTime)
{
STDTIME_ENUM_FUNC (MmsTimeOfDay6ToStdTime)
STDTIME_RET (MmsTimeOfDay6ExToStdTime (pMmsTimeOfDay6, 0, 0, pStdTime));
} /* MmsTimeOfDay6ToStdTime */

View File

@@ -0,0 +1,169 @@
/*****************************************************************************/
/* SISCO SOFTWARE MODULE HEADER **********************************************/
/*****************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 2006 All Rights Reserved */
/* */
/* MODULE NAME : stdtime_mms_utctime.c */
/* PRODUCT(S) : Standard Time Management Library */
/* */
/* MODULE DESCRIPTION: */
/* Support for MMS UTC TIME conversions to/from STDTIME */
/* */
/* MODIFICATION LOG: */
/* Date Who Rev Comments */
/* -------- --- --- ----------------------------------------------------- */
/* 02/20/08 JRB 02 Simplified StdTimeToMmsUtcTime (fixes rounding bug). */
/* Simplified MmsUtcTimeToStdTime. */
/* Delete StdTimeFields functions. */
/* 10/05/06 RLH 01 Created */
/*****************************************************************************/
#include "stdtime.h"
#include "stdtime_mms_utctime.h"
/*** MmsUtcTime initialization function **************************************/
STDTIME_MMS_UTC_TIME StdTimeApiZeroMmsUtcTime ()
{
STDTIME_MMS_UTC_TIME zero = {0};
return zero;
} /* StdTimeApiZeroMmsUtcTime */
/*** MmsUtcTime functions ****************************************************/
/*-***************************************************************************/
/* StdTimeToMmsUtcTime */
/* convert: StdTime structure to MMS_UTC_TIME */
/* method: convert to TIMETYPE, then calculate binary fraction of second */
/*****************************************************************************/
STDTIME_RC StdTimeToMmsUtcTime (
const STDTIME * /*I*/ pStdTime,
STDTIME_MMS_UTC_TIME * /*O*/ pMmsUtcTime)
{
QUADLIB_I64 qFrac;
QUADLIB_I64 qRem;
QUADLIB_I64 q10_7;
QUADLIB_I64 q2_24;
time_t timet;
int32_t nsec;
STDTIME_ENUM_FUNC (StdTimeToMmsUtcTime)
if (pMmsUtcTime == NULL)
{
STDTIME_RET_EC (null_argument);
}
if STDTIME_IFNOT (StdTimeToTimeTypeEx (pStdTime, &timet, &nsec))
{
STDTIME_RET_RC;
}
/* Init qFrac to number of 100-nsec intervals. */
QUADLIB_I64_HI(qFrac) = 0;
QUADLIB_I64_LO(qFrac) = nsec / 100;
QUADLIB_I64_HI(q10_7) = 0;
QUADLIB_I64_LO(q10_7) = 10000000;
QUADLIB_I64_HI(q2_24) = 0;
QUADLIB_I64_LO(q2_24) = 0x1000000;
/* multiply by range of UTC fraction */
QUADLIB_I64_MUL_EQ (qFrac, q2_24);
/* divide out number of 100-ns intervals */
/* as 100-ns intervals approaches 10_7, frac approaches 2_24 */
qFrac = QuadLibI64DivMod (qFrac, q10_7, &qRem);
/* assign UTC values to output argument */
pMmsUtcTime->secs = (int32_t) timet;
pMmsUtcTime->fraction = (int32_t) QUADLIB_I64_LO(qFrac);
pMmsUtcTime->qflags = 0; /* IS THIS CORRECT ? */
STDTIME_RET_OK;
} /* StdTimeToMmsUtcTime */
/*-***************************************************************************/
/* MmsUtcTimeToStdTime */
/* convert: MMS_UTC_TIME to StdTime structure */
/*****************************************************************************/
STDTIME_RC MmsUtcTimeToStdTime (
const STDTIME_MMS_UTC_TIME * /*I*/ pMmsUtcTime,
STDTIME * /*O*/ pStdTime)
{
QUADLIB_I64 qFrac;
QUADLIB_I64 qRem;
QUADLIB_I64 q10_7;
QUADLIB_I64 q2_24;
int32_t nsec; /* nanoseconds */
STDTIME_ENUM_FUNC (MmsUtcTimeToStdTime)
if (pStdTime == NULL)
{
STDTIME_RET_EC (null_argument);
}
*pStdTime = ZeroStdTime ();
if (pMmsUtcTime == NULL)
{
STDTIME_RET_EC (null_argument);
}
/* Convert fraction to nsec, then call TimeTypeExToStdTime. */
/* obtain number of binary fractional units */
QUADLIB_I64_HI(q10_7) = 0;
QUADLIB_I64_LO(q10_7) = 10000000;
QUADLIB_I64_HI(q2_24) = 0;
QUADLIB_I64_LO(q2_24) = 0x1000000;
QUADLIB_I64_HI(qFrac) = 0;
QUADLIB_I64_LO(qFrac) = pMmsUtcTime->fraction;
/* multiply by range of 100-ns intervals */
QUADLIB_I64_MUL_EQ (qFrac, q10_7);
/* divide out number of binary fractional units */
/* as fractional units approach 2**24, frac approaches 10**7 */
qFrac = QuadLibI64DivMod (qFrac, q2_24, &qRem);
if (QUADLIB_I64_LO(qRem) >= (10000000 / 2))
{
QUADLIB_I64_LO(qFrac)++; /* ROUND UP */
}
nsec = (QUADLIB_I32_CASTI64 (qFrac)) * 100;
/* Convert and put result at pointer pStdTime. */
if STDTIME_IFNOT (TimeTypeExToStdTime (pMmsUtcTime->secs, nsec, pStdTime))
{
STDTIME_RET_RC;
}
STDTIME_RET_OK;
} /* MmsUtcTimeToStdTime */

File diff suppressed because it is too large Load Diff

1348
mmslib/util/stdtime_w32.c Normal file

File diff suppressed because it is too large Load Diff

479
mmslib/util/stime.c Normal file
View File

@@ -0,0 +1,479 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1993 - 2007, All Rights Reserved */
/* */
/* MODULE NAME : stime.c */
/* PRODUCT(S) : */
/* */
/* MODULE DESCRIPTION : */
/* This module implements functions that can be used in */
/* differencial timimg. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 01/15/07 EJV 30 Chg S_LOCK_RESOURCES to S_LOCK_UTIL_RESOURCES*/
/* 10/26/06 EJV 29 HP-UX: changed from gettimeofday() to times()*/
/* 07/13/06 EJV 28 Sun: changed from gettimeofday() to times(). */
/* 06/20/06 RKR 27 removed a piece of code from _sGetSysMsTime */
/* 05/31/06 GLB 26 Integrated porting changes for VMS */
/* 03/23/06 EJV 25 Corrected VMS chg to _sGetSysMsTime. */
/* Rearranged includes, del windows.h. */
/* 01/30/06 GLB 24 Integrated porting changes for VMS */
/* 01/30/06 EJV 23 _WIN32 _sGetSysMsTime: added (ST_INT64) cast */
/* before (ST_DOUBLE) to eliminate VS6 compiler*/
/* error after changing ST_UINT64 define to */
/* unsigned __int64. */
/* 06/10/05 EJV 22 Revised the repeating code. */
/* Linux, QNX: rpl gettimeofday() with times(). */
/* Del MSDOS and __OS2__ code. */
/* Del sGetMsStartTime, sSetMsStartTime */
/* Renamed lastTime to initTime. */
/* 03/11/04 GLB 21 Remove "thisFileName" */
/* 12/09/03 JRB 20 Add LYNX support. */
/* 11/04/03 JRB 19 Add sMsSleep (replaces gs_sleep). */
/* 10/13/03 EJV 18 Chg defined(vms) to defined(__VMS) */
/* 04/08/03 EJV 17 Use S_LOCK_RESOURCES (better for non-MT apps)*/
/* 03/21/03 EJV 16 _WIN32: sGetMsTime, sGetSysMsTime must be */
/* protected by mutex,prevent incorect wrapCount*/
/* 03/18/03 EJV 15 Corrected __QNX4__ to __QNX__ (per JRB). */
/* 03/18/03 EJV 14 sGetMsTime: fixed lastTime casting problem */
/* (made lastTime ST_UINT on _WIN32). */
/* 02/17/03 CRM 13 Added "defined(linux)" code. */
/* 02/17/03 JRB 12 Add "sysincs.h" & del other includes. */
/* Del obsolete _WINDOWS, MSOS2 code. */
/* 02/17/03 EJV 11 sGetMsTime, sGetSysMsTime: fixed wrap counter*/
/* Auto-initialize funs with call to stimeInit()*/
/* Chg S_LOCK_RESOURCES to gs_get_sem,avoid loop*/
/* 06/05/02 MDE,EJV 10 sGetMsTime: workaround some math problem */
/* 11/29/01 EJV 09 Del code for old LATT, XENIX, ultrix, RMX86. */
/* 06/19/01 JRB 08 Chg S_LOCK_COMMON.. to S_LOCK_RESOURCES so */
/* glbsem doesn't log (caused infinite loop). */
/* 04/19/00 JRB 07 Lint cleanup. */
/* 11/18/99 EJV 06 Added code to capture wrapping of ms counter */
/* for _WIN32 and PHARLAP_ETS. */
/* 09/13/99 MDE 05 Added SD_CONST modifiers */
/* 11/05/97 DSF 04 Added sGetSysMsTime () */
/* 09/22/97 JRB 03 Fixed some #if's. */
/* 09/09/97 JRB 02 Use GetTickCount for PHARLAP_ETS. */
/* 09/08/97 EJV 01 Added code for QNX. */
/* 04/02/97 DTL 7.00 MMSEASE 7.0 release. See MODL70.DOC for */
/* history. */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#include "glbsem.h"
#if defined (_WIN32)
#include <mmsystem.h>
#if defined (PHARLAP_ETS)
#define timeGetTime GetTickCount /* timeGetTime not supported */
#endif /* PHARLAP_ETS */
#endif
#if defined(__VMS)
#include <starlet.h>
#endif
#if defined(linux) || defined(sun) || defined(__hpux) || \
defined(__QNX__) || defined(__LYNX)
#include <sys/times.h> /* for struct tms */
#endif
/************************************************************************/
/* NOTE: Users porting this code to new platform should not use the */
/* gettimeofday() or similar functions. When the system time */
/* is changed, for example during clock synchronization, the */
/* gettimeofday() would also reflect this change. */
/* Application should use times() function if available. */
/* */
/* DEBUG: On UNIX systems we should implement the sTime functions */
/* the same way as on LINUX. */
/************************************************************************/
/*------------------------------------------------------*/
/* stime module variables */
/*------------------------------------------------------*/
#if defined(linux) || defined(sun) || defined(__hpux)
static ST_UINT64 wrapCount; /* ms, cumulative wrapped time ticks elapsed since program start*/
#elif (defined (__QNX__) || defined(__LYNX))
static ST_DOUBLE wrapCount; /* ms, cumulative wrapped time ticks elapsed since program start*/
#elif defined (_WIN32)
static ST_UINT64 wrapCount; /* wrap count (see timeGetTime or GetTickTime) */
#endif
#if defined (__ECOS)
#define ST_UINT64 unsigned long long
static unsigned long long wrapCount;
#endif
static ST_ULONG ticksPerSec; /* system dependent value, returned by sysconf(_SC_CLK_TCK) */
static ST_ULONG lastCheckTime; /* last time checked, used to detect clock_t overflow */
static ST_DOUBLE initMsTime; /* in ms, store initialization time */
static ST_INT initialized; /* SD_TRUE if stimeInit func successful */
/************************************************************************/
/* _sGetSysMsTime */
/*----------------------------------------------------------------------*/
/* Combined code from sGetMsTime and sGetSysMsTime, now also called by */
/* stimeInit. */
/* */
/* NOTE: this new implementation on LINUX uses the times() function */
/* to obtain the "number of clock ticks that have elapsed since */
/* an arbitrary point in the past. For Linux this point is the */
/* moment the system was booted. The return from times() may */
/* overflow the possible range of clock_t." */
/* The revision of the IEEE Std 1003.1, 2004 allows the that */
/* reference point can be the start-up time of the process */
/* rather than system start-up time. */
/* IMPORTANT: */
/* This implementation is assuming that POSIX compliant clock_t */
/* type is defined as long (4 bytes integer). If this is not the */
/* case then the code needs to be revised! */
/* */
/* DEBUG: In the future LINUX implementation should be used for all */
/* UNIX systems. */
/************************************************************************/
static ST_DOUBLE _sGetSysMsTime (ST_VOID)
{
ST_DOUBLE sysMsTime = (ST_DOUBLE) 0.0; /* system time to be returned */
#if defined(linux) || defined(sun) || defined(__hpux)
{
struct tms tmsTime; /* must be passed to times() but we do not use it */
ST_ULONG sysTime;
sysTime = (ST_ULONG) times (&tmsTime);
if (sysTime != (ST_ULONG) -1)
{
/* NOTE: The value returned from the times() function (number of ticks */
/* from some fixed point in time) will wrap. */
/* Wrapping depends on the frequency (ticksPerSec) and can be as */
/* often as every 39 minutes. This function needs to be called */
/* frequently enough to detect when the value wraps. */
#if 0 /* DEBUG: code to test wrapping, */
/* trigger the wrapping every 60 seconds if this funct is called */
if ( (sysTime > ticksPerSec) && /* don't wrap before 1-st second elapses*/
((sysTime / ticksPerSec) % 60 == 0) )
lastCheckTime=sysTime+1; /* tweek the lastCheckTime */
#endif
if (sysTime < lastCheckTime)
/* the ticks counter wrapped to 0 */
wrapCount += ((ST_UINT64) 1 << 32); /* increment the high part of ST_UINT64 */
/* convert the sys time to ms accounting for possible wrap */
/* (switch math operations order / with * for better precission, avoid floating point math) */
sysMsTime = (ST_DOUBLE)((wrapCount + (ST_UINT64) sysTime) * 1000 / (ST_UINT64) ticksPerSec);
lastCheckTime = sysTime; /* save for next check */
}
else
{
ST_INT err;
err = errno; /* can't log this error but we could see it in debugger */
}
}
#elif defined(__ECOS)
{
struct timeval tp;
struct timezone tzp;
gettimeofday (&tp, &tzp); /* avoid floating math */
sysMsTime = (ST_DOUBLE) ( (ST_UINT64) ((ST_ULONG) tp.tv_sec) * (ST_UINT64) 1000 +
(ST_UINT64) ((ST_ULONG) tp.tv_usec) / (ST_UINT64) 1000 );
#if 0
cyg_tick_count_t sysTime; /* in ecos, cyg_tick_count_t is defined by cyg_uint64 */
sysTime = cyg_current_time();
sysMsTime = (ST_DOUBLE)((wrapCount + (ST_UINT64) sysTime) * 1000 / (ST_UINT64) ticksPerSec);
#endif
}
#elif defined(_AIX) || (defined(__alpha) && !defined(__VMS)) /* Tru64 alpha */
{
struct timeval tp;
struct timezone tzp;
gettimeofday (&tp, &tzp); /* avoid floating math */
sysMsTime = (ST_DOUBLE) ( (ST_UINT64) ((ST_ULONG) tp.tv_sec) * (ST_UINT64) 1000 +
(ST_UINT64) ((ST_ULONG) tp.tv_usec) / (ST_UINT64) 1000 );
}
#elif defined(__VMS) /* OpenVMS non-specific */
{
struct timeval tp;
ST_LONG tzp;
gettimeofday (&tp, &tzp); /* avoid floating math */
sysMsTime = (ST_DOUBLE)
(
/*(ST_UINT64)*/ ((ST_ULONG) tp.tv_sec) * /*(ST_UINT64)*/ 1000 +
/*(ST_UINT64)*/ ((ST_ULONG) tp.tv_usec) / /*(ST_UINT64)*/ 1000
);
}
#elif defined (VXWORKS)
{
/*renxiaobao add*/
struct timeval tp;
vx_gettimeofday (&tp,0);
sysMsTime = ((ST_DOUBLE)tp.tv_sec)*1000 + ((ST_DOUBLE)tp.tv_usec)/1000;
/*sysMsTime = (ST_DOUBLE) time (NULL) * 1000;*/
}
#elif (defined (__QNX__) || defined(__LYNX))
{
struct tms tmsTime; /* must be passed to times() but we do not use it */
ST_ULONG sysTime;
sysTime = (ST_ULONG) times (&tmsTime);
if (sysTime != (ST_ULONG) -1)
{
/* NOTE: The value returned from the times() function (number of ticks */
/* from some fixed point in time) will wrap. */
/* Wrapping depends on the frequency (ticksPerSec) and can be as */
/* often as every 39 minutes. This function needs to be called */
/* frequently enough to detect when the value wraps. */
if (sysTime < lastCheckTime)
/* the ticks counter wrapped to 0 */
wrapCount += (ST_DOUBLE) (ULONG_MAX);
/* convert the sys time to ms accounting for possible wrap, */
/* note that we do not have ST_INT64 support on QNX or LYNX systems */
sysMsTime = (ST_DOUBLE)((wrapCount + (ST_DOUBLE) sysTime) * 1000.0 / (ST_DOUBLE) ticksPerSec);
lastCheckTime = sysTime; /* save for next check */
}
}
#elif defined (_WIN32)
{
ST_ULONG msTime;
/* the timeGetTime function retrieves the system time, in milliseconds.*/
/* The system time is the time elapsed since Windows was started. */
/* NOTE: The timeGetTime and GetTickCount (used for PHARLAP_ETS) */
/* return DWORD value that wraps to 0 every 49 days. */
/* We need to detect the wrap up moment and save it. */
msTime = (ST_ULONG) timeGetTime ();
if ( msTime < lastCheckTime )
/* the ms counter wrapped to 0 */
wrapCount += ( (ST_UINT64) 1 << 32 ); /* increment the high part of ST_UINT64 */
sysMsTime = (ST_DOUBLE) (ST_INT64) (wrapCount + (ST_UINT64) msTime);
/* NOTE VC V6.0 compiler: the compiler generates error for the */
/* conversion of unsigned __int64 to double. We will cast to */
/* ST_INT64 before the ST_DOUBLE cast. This should work */
/* because the sum of both numbers will 'never' be negative. */
lastCheckTime = msTime; /* save for next check */
}
#else
#error Missing stime module implementation for this platform
#endif
return (sysMsTime);
}
/************************************************************************/
/* _stimeReset */
/*----------------------------------------------------------------------*/
/* Resets stime module variables. */
/************************************************************************/
static ST_RET _stimeReset (ST_VOID)
{
ST_RET rtn = SD_SUCCESS;
#if (defined(linux) || defined(sun) || defined(__hpux) || defined(_WIN32))
wrapCount = 0;
lastCheckTime = 0;
#elif (defined(__QNX__) || defined(__LYNX))
wrapCount = 0.0;
lastCheckTime = 0;
#endif
initMsTime = _sGetSysMsTime ();
return (rtn);
}
/************************************************************************/
/* stimeInit */
/*----------------------------------------------------------------------*/
/* Initialize stime module variables. */
/************************************************************************/
ST_RET stimeInit (ST_VOID)
{
ST_RET rtn = SD_SUCCESS;
/* Allow multiple calls */
if (initialized)
return (rtn);
S_LOCK_UTIL_RESOURCES (); /* NOTE: this macro is now using non-logging gs_get_sem() */
#if defined(linux) || defined(sun) || defined(__hpux) || defined(__QNX__) || defined(__LYNX)
{
ticksPerSec = 0;
ticksPerSec = (ST_ULONG) sysconf(_SC_CLK_TCK);
if (ticksPerSec == (ST_ULONG) -1L || ticksPerSec == 0)
rtn = SD_FAILURE; /* some error getting the number of clock ticks per second */
}
#endif
if (rtn == SD_SUCCESS)
{
rtn = _stimeReset ();
if (rtn == SD_SUCCESS)
initialized = SD_TRUE;
}
S_UNLOCK_UTIL_RESOURCES ();
return (rtn);
}
/************************************************************************/
/* sGetMsTime */
/*----------------------------------------------------------------------*/
/* Returns time in milliseconds form the start of the program. */
/************************************************************************/
ST_DOUBLE sGetMsTime (ST_VOID)
{
ST_DOUBLE sysMsTime, retMsTime;
if (!initialized)
if (stimeInit () != SD_SUCCESS)
return ((ST_DOUBLE)0.0);
S_LOCK_UTIL_RESOURCES ();
sysMsTime = _sGetSysMsTime();
retMsTime = sysMsTime - initMsTime;
S_UNLOCK_UTIL_RESOURCES ();
return (retMsTime);
}
/************************************************************************/
/* sGetSysMsTime */
/*----------------------------------------------------------------------*/
/* Returns system time in milliseconds (time from an arbitrary point */
/* like system start or program start). */
/************************************************************************/
ST_DOUBLE sGetSysMsTime (ST_VOID)
{
ST_DOUBLE sysMsTime;
if (!initialized)
if (stimeInit () != SD_SUCCESS)
return ((ST_DOUBLE)0.0);
S_LOCK_UTIL_RESOURCES ();
sysMsTime = _sGetSysMsTime();
S_UNLOCK_UTIL_RESOURCES ();
return (sysMsTime);
}
/************************************************************************/
/* sResetMsTime */
/*----------------------------------------------------------------------*/
/* Reset stime module variables. */
/************************************************************************/
ST_VOID sResetMsTime (ST_VOID)
{
if (!initialized)
{
stimeInit (); /* calls the _stimeReset() */
return;
}
S_LOCK_UTIL_RESOURCES ();
_stimeReset ();
S_UNLOCK_UTIL_RESOURCES ();
}
/************************************************************************/
/* stimeExit */
/*----------------------------------------------------------------------*/
/* Terminate timer use. */
/************************************************************************/
ST_VOID stimeExit (ST_VOID)
{
if (!initialized)
return;
S_LOCK_UTIL_RESOURCES ();
initialized = SD_FALSE;
S_UNLOCK_UTIL_RESOURCES ();
}
/************************************************************************/
/* sMsSleep */
/*----------------------------------------------------------------------*/
/* Calls system function to suspend current task or thread for */
/* specified amount of time. */
/* Parameters: */
/* ST_LONG ms Number of milliseconds to sleep */
/* Return values: */
/* none */
/************************************************************************/
#if defined(_WIN32)
ST_VOID sMsSleep (ST_LONG ms)
{
Sleep (ms);
}
#elif defined(__VMS)
ST_VOID sMsSleep (ST_LONG ms)
{
ST_ULONG msec = (ST_ULONG) ms;
unsigned int us;
while (msec > 0)
{
if (msec >= 1000)
{
us = 999999; /* microseconds, it must be less than 1000000 for usleep */
msec -= 1000;
}
else
{
us = msec * 1000;
msec = 0;
}
usleep (us); /* unistd.h */
}
}
#else /* all other systems */
/* This version of the function uses the POSIX nanosleep function. */
ST_VOID sMsSleep (ST_LONG ms)
{
struct timespec rqtp;
rqtp.tv_sec = ms / 1000;
rqtp.tv_nsec = (ms % 1000) * 1000000; /* 1000 ms/us, 1000 us/ns ... */
nanosleep (&rqtp, NULL); /* should be available on AIX v5.x */
}
#endif /* all other systems */

947
mmslib/util/str_util.c Normal file
View File

@@ -0,0 +1,947 @@
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 2000 - 2007 All Rights Reserved */
/* */
/* MODULE NAME : str_util.c */
/* PRODUCT(S) : General Use */
/* */
/* MODULE DESCRIPTION : */
/* General purpose string manipulation functions. */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* ascii_to_hex_str */
/* hex_to_ascii_str */
/* strnicmp (UNIX) */
/* strcmpi (UNIX) */
/* stricmp (UNIX) */
/* strncat_maxstrlen */
/* strncpy_safe */
/* asciiToSlong */
/* asciiToUlong */
/* asciiToSint */
/* asciiToUint */
/* asciiToSint32 */
/* asciiToUint32 */
/* asciiToSint16 */
/* asciiToUint16 */
/* asciiToSint8 */
/* asciiToUint8 */
/* asciiToUchar */
/* asciiToFloat */
/* asciiToDouble */
/* sInt8ToAscii */
/* uInt8ToAscii */
/* sInt16ToAscii */
/* uInt16ToAscii */
/* sInt32ToAscii */
/* uInt32ToAscii */
/* sIntToAscii */
/* uIntToAscii */
/* sLongToAscii */
/* uLongToAscii */
/* getKeywordFromFile */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 11/07/07 EJV 23 Check before defining INT32_MAX, UINT32_MAX. */
/* 10/29/07 JRB 22 Add strncat_maxstrlen. Del strncat_safe (len */
/* was wrong), use strncat or strncat_maxstrlen.*/
/* 10/11/07 JRB 21 Add asciiToSint32, asciiToUint32 */
/* 08/03/07 JRB 20 get_next_string: don't ignore extra delimiters*/
/* They now indicate empty field (as in Excel). */
/* 02/13/06 DSF 19 Migrate to VS.NET 2005 */
/* 07/28/05 DWL 18 Corrected microsecond resolution, use const */
/* ST_CHAR* in asciiTo* functions. */
/* 03/14/05 JRB 17 Add get_next_string. */
/* 12/03/04 JRB 16 Use strcasecmp, strncasecmp if supported. */
/* Don't need SISCO strnicmp, etc. */
/* 07/09/04 JRB 15 Add strncat_safe, strncpy_safe. */
/* 03/09/04 EJV 14 Added getKeywordFromFile function. */
/* 12/12/03 JRB 13 Add LYNX support. */
/* 12/10/03 MDE 12 Added itoa/ltoa/utoa/ultoa replacements */
/* 04/10/03 DSF 11 Added strnstr */
/* 02/20/03 JRB 10 Del PSOS code. */
/* 12/20/02 CRM 09 Added "defined(linux)" for strcmpi, etc. */
/* 03/01/02 EJV 08 Can't check doubleNum < FLT_MIN (0.0 fails). */
/* 02/28/02 EJV 07 Added asciiToFloat, asciiToDouble. */
/* 02/25/02 EJV 06 Replaced non-ANSI ltoa with sprintf. */
/* Added asciiToUlong, asciiToUint16, */
/* asciiToUint8, asciiToSint, asciiToUint */
/* hex_to_ascii_str: added param hex_no_spaces. */
/* asciiToxxx:eliminated dependency on sx_defs.h*/
/* 12/09/01 GLB 05 Added asciiToSlong, asciiToSint16, */
/* asciiToSint8, asciiToUchar */
/* 05/21/01 MDE 04 Added bitstring_to_ascii_str */
/* 01/19/01 EJV 03 Moved strcmpi,stricmp,strnicmp from cfg_util */
/* 11/02/00 MDE 02 Added _hex_no_spaces */
/* 02/03/00 JRB 01 Created */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#include "str_util.h"
#include "slog.h"
#include <float.h>
#include <math.h>
#ifdef DEBUG_SISCO
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
#endif
/* NOTE: limits.h (included in sysincs.h) should have these defined. */
/* Used to compare to LONG_MAX, ULONG_MAX to detect the long size.*/
#if !defined(INT32_MAX)
#define INT32_MAX 0x7fffffff
#endif
#if !defined(UINT32_MAX)
#define UINT32_MAX 0xffffffff
#endif
/************************************************************************/
/* ascii_to_hex_str */
/************************************************************************/
ST_RET ascii_to_hex_str (
ST_UCHAR *hstr, /* hex string */
ST_UINT *hlen_out, /* ptr to hex len to be set */
ST_UINT hlen_max, /* maximum hex len to allow. */
ST_CHAR *astr) /* ascii string */
{
ST_INT digit;
ST_BOOLEAN nibble; /* SD_TRUE if nibble read, SD_FALSE if whole byte read*/
*hlen_out = 0;
nibble = SD_FALSE;
for ( ; *astr; astr++) /* read until NULL terminator */
{
if (isxdigit (*astr)) /* get hex number */
{
if (*hlen_out >= hlen_max)
{ /* hstr already full. Can't add digit. */
return (SD_FAILURE);
}
digit = *astr;
digit = isdigit (digit) ? digit - '0' : 10 + (toupper (digit) - 'A');
if (nibble)
{ /* set low nibble */
nibble = SD_FALSE;
hstr[*hlen_out] |= (ST_UCHAR) digit;
(*hlen_out)++;
}
else
{ /* set high nibble */
nibble = SD_TRUE;
hstr[*hlen_out] = (ST_UCHAR) digit << 4;
}
}
else if (isspace (*astr))
continue;
else
{ /* not hex digit, not white space, NOT GOOD. */
return (SD_FAILURE);
}
} /* end "while" */
if (nibble)
{ /* Only got half of byte. */
return (SD_FAILURE);
}
return (SD_SUCCESS);
}
/************************************************************************/
/* hex_to_ascii_str */
/* To make it more readable, a 'blank' is inserted after every 2 digits */
/* in the ascii string. The ascii string is NULL terminated. */
/* The ascii buffer must be at least 3 times the length of the hex */
/* string (hlen) to allow for the blanks and the NULL terminator. */
/************************************************************************/
#define cvt_nibble(a) ((ST_UCHAR) ((a) > 9 ? (a) + 'A' - 10 : (a) + '0'))
ST_VOID hex_to_ascii_str (
ST_CHAR *astr, /* ascii string */
ST_UCHAR *hstr, /* hex string */
ST_UINT hlen, /* len of hex string */
ST_BOOLEAN hex_no_spaces)
{
ST_UINT j;
ST_INT hex_index = 0;
ST_UCHAR ch;
ST_UCHAR hex;
for (j = 0; j < hlen; j++)
{
if (j && hex_no_spaces != SD_TRUE)
astr[hex_index++] = ' '; /* space between bytes, but not before first*/
ch = *hstr++; /* get next character */
hex = (ch >> 4) & (ST_UCHAR) 0x0f;/* write HEX chars for the byte */
hex = cvt_nibble(hex);
astr[hex_index++] = hex;
hex = ch & (ST_UCHAR) 0x0f;
hex = cvt_nibble(hex);
astr[hex_index++] = hex;
}
astr[hex_index] = '\0'; /* NULL terminate it. */
}
/************************************************************************/
/* strnstr */
/************************************************************************/
char * strnstr (char *str1, char *str2, int len)
{
char *cp = (char *) str1;
char *s1, *s2;
int cl;
if ( !*str2 )
return((char *)str1);
while (*cp && len)
{
cl = len;
s1 = cp;
s2 = (char *) str2;
while (*s1 && *s2 && cl && !(*s1-*s2) )
s1++, s2++, cl--;
if (!*s2)
return(cp);
cp++;
len--;
}
return(NULL);
}
/* These functions used when system libraries don't provide them.
* Most UNIX-like systems provide similar functions strcasecmp &
* strncasecmp. On those systems, strnicmp etc. are remapped to strcasecmp &
* strncasecmp (see str_util.h), so these functions NOT needed.
*/
#if defined(VXWORKS) || defined(__LYNX) || defined(__ECOS)
/************************************************************************/
/* strnicmp */
/************************************************************************/
ST_INT strnicmp (ST_CHAR *str1, ST_CHAR *str2, ST_INT n )
{
ST_INT i = 0;
ST_INT test = 1;
for (i = 0; i < n; i++)
{
if ( tolower ( *(str1+i) ) != tolower ( *(str2+i) ) )
{
test = 0;
break;
}
}
if (test == 1)
return (0);
else
if ( tolower ( *(str1+i) ) > tolower ( *(str2+i) ) )
return (1);
else
return (-1);
}
/************************************************************************/
/* strcmpi */
/************************************************************************/
ST_INT strcmpi (ST_CHAR *str1, ST_CHAR *str2)
{
ST_INT iLen1, iLen2;
iLen1 = strlen(str1);
iLen2 = strlen(str2);
return(strnicmp(str1, str2, ((iLen1 > iLen2) ? iLen1 : iLen2)));
}
/************************************************************************/
/* stricmp */
/************************************************************************/
ST_INT stricmp (ST_CHAR *str1, ST_CHAR *str2)
{
return(strcmpi(str1, str2));
}
#endif /* system libs don't provide these functs & don't support strcasecmp, strncasecmp.*/
/************************************************************************/
/* strncat_maxstrlen */
/* Similar to strncat but third arg is the maximum string length. */
/* Destination string "dest" is always NULL terminated. */
/* NOTE: Destination buffer size should always be at least */
/* (maxstrlen+1) so there is room for NULL. */
/* RETURNS: SD_SUCCESS or SD_FAILURE if maxstrlen already exceeded. */
/************************************************************************/
ST_RET strncat_maxstrlen (char *dest, char *src, size_t maxstrlen)
{
size_t dest_len;
ST_RET retcode;
dest_len = strlen (dest);
if (dest_len < maxstrlen)
{
strncat (dest, src, maxstrlen-dest_len); /* always NULL-terminates dest*/
retcode = SD_SUCCESS;
}
else
retcode = SD_FAILURE; /* "dest" is already too long. Don't do anything. */
return (retcode);
}
/************************************************************************/
/* strncpy_safe */
/* Same as strncpy but always NULL terminates "dest" string. */
/* strncpy return is useless so this function doesn't bother with return.*/
/************************************************************************/
ST_VOID strncpy_safe (char *dest, char *src, int max_len)
{
strncpy (dest, src, max_len);
dest[max_len] = '\0';
}
/************************************************************************/
/* asciiToSlong */
/************************************************************************/
ST_RET asciiToSlong (const ST_CHAR *astr, /* ascii string */
ST_LONG *sLong) /* ptr to long value obtained
from converted ascii string */
{
ST_CHAR *retPtr;
*sLong = 0;
errno = 0;
/* convert ascii string to signed long */
*sLong = strtol (astr, &retPtr, 10);
if (retPtr == astr || errno != 0)
return (SD_FAILURE); /* conversion error */
return SD_SUCCESS;
}
/************************************************************************/
/* asciiToUlong */
/************************************************************************/
ST_RET asciiToUlong (const ST_CHAR *astr, /* ascii string */
ST_ULONG *uLong) /* ptr to long value obtained
from converted ascii string */
{
ST_CHAR *retPtr;
*uLong = 0;
errno = 0;
/* convert ascii string to unsigned long */
*uLong = strtoul (astr, &retPtr, 10);
if (retPtr == astr || errno != 0)
return (SD_FAILURE); /* conversion error */
return SD_SUCCESS;
}
/************************************************************************/
/* asciiToSint */
/************************************************************************/
ST_RET asciiToSint (const ST_CHAR *astr, /* ascii string */
ST_INT *sInt) /* ptr to value obtained
from converted ascii string */
{
ST_CHAR *retPtr;
ST_LONG sLong = 0;
*sInt = 0;
errno = 0;
/* convert ascii string to signed long */
sLong = strtol (astr, &retPtr, 10);
if (retPtr == astr || errno != 0)
return (SD_FAILURE); /* conversion error */
#if (INT_MAX != LONG_MAX) /* if they are same, don't need to check */
if (sLong < INT_MIN || sLong > INT_MAX)
/* value does not fit in the range of ST_INT */
return SD_FAILURE;
#endif
*sInt = (ST_INT) sLong;
return SD_SUCCESS;
}
/************************************************************************/
/* asciiToUint */
/************************************************************************/
ST_RET asciiToUint (const ST_CHAR *astr, /* ascii string */
ST_UINT *uInt) /* ptr to value obtained
from converted ascii string */
{
ST_CHAR *retPtr;
ST_ULONG uLong = 0;
*uInt = 0;
errno = 0;
/* convert ascii string to unsigned long */
uLong = strtoul (astr, &retPtr, 10);
if (retPtr == astr || errno != 0)
return (SD_FAILURE); /* conversion error */
#if (UINT_MAX != ULONG_MAX) /* if they are same, don't need to check */
if (uLong > UINT_MAX)
/* value does not fit in the range of ST_UINT */
return SD_FAILURE;
#endif
*uInt = (ST_UINT) uLong;
return SD_SUCCESS;
}
/************************************************************************/
/* asciiToSint32 */
/************************************************************************/
ST_RET asciiToSint32 (const ST_CHAR *astr, /* ascii string */
ST_INT32 *value) /* ptr to converted value*/
{
ST_CHAR *retPtr;
ST_LONG sLong = 0;
*value = 0;
errno = 0;
/* convert ascii string to signed long */
sLong = strtol (astr, &retPtr, 10);
if (retPtr == astr || errno != 0)
return (SD_FAILURE); /* conversion error */
#if (LONG_MAX < INT32_MAX) /* LONG smaller than 32 bits */
#error This code will not work on this platform.
#endif
#if (LONG_MAX > INT32_MAX) /* LONG bigger than 32 bits */
/* DEBUG: test this on 64-bit system. */
if (sLong > INT32_MAX || sLong < (-0x80000000))
/* value does not fit in the range of ST_INT32 */
return (SD_FAILURE);
#endif
/* if (LONG_MAX == INT32_MAX), long is same as ST_INT32, */
/* so no need to chk range. */
*value = (ST_INT32) sLong;
return (SD_SUCCESS);
}
/************************************************************************/
/* asciiToUint32 */
/************************************************************************/
ST_RET asciiToUint32 (const ST_CHAR *astr, /* ascii string */
ST_UINT32 *value) /* ptr to converted value*/
{
ST_CHAR *retPtr;
ST_ULONG uLong = 0;
*value = 0;
errno = 0;
/* convert ascii string to unsigned long */
uLong = strtoul (astr, &retPtr, 10);
if (retPtr == astr || errno != 0)
return (SD_FAILURE); /* conversion error */
#if (ULONG_MAX < UINT32_MAX) /* ULONG smaller than 32 bits */
#error This code will not work on this platform.
#endif
#if (ULONG_MAX > UINT32_MAX) /* ULONG bigger than 32 bits */
if (uLong > UINT32_MAX)
/* value does not fit in the range of ST_UINT32 */
return (SD_FAILURE);
#endif
/* if (ULONG_MAX == UINT32_MAX), unsigned long is same as ST_UINT32,*/
/* so no need to chk range. */
*value = (ST_UINT32) uLong;
return (SD_SUCCESS);
}
/************************************************************************/
/* asciiToSint16 */
/************************************************************************/
ST_RET asciiToSint16 (const ST_CHAR *astr,/* ascii string */
ST_INT16 *sInt16) /* ptr to value obtained
from converted ascii string */
{
ST_CHAR *retPtr;
ST_LONG sLong = 0;
*sInt16 = 0;
errno = 0;
/* convert ascii string to signed long */
sLong = strtol (astr, &retPtr, 10);
if (retPtr == astr || errno != 0)
return (SD_FAILURE); /* conversion error */
if (sLong < SHRT_MIN || sLong > SHRT_MAX)
/* value does not fit in the range of ST_INT16 */
return SD_FAILURE;
*sInt16 = (ST_INT16) sLong;
return SD_SUCCESS;
}
/************************************************************************/
/* asciiToUint16 */
/************************************************************************/
ST_RET asciiToUint16 (const ST_CHAR *astr, /* ascii string */
ST_UINT16 *uInt16) /* ptr to value obtained
from converted ascii string */
{
ST_CHAR *retPtr;
ST_ULONG uLong = 0;
*uInt16 = 0;
errno = 0;
/* convert ascii string to unsigned long */
uLong = strtoul (astr, &retPtr, 10);
if (retPtr == astr || errno != 0)
return (SD_FAILURE); /* conversion error */
if (uLong > USHRT_MAX)
/* value does not fit in the range of ST_UINT16 */
return SD_FAILURE;
*uInt16 = (ST_UINT16) uLong;
return SD_SUCCESS;
}
/************************************************************************/
/* asciiToUchar */
/************************************************************************/
ST_RET asciiToUchar (const ST_CHAR *astr, /* ascii string */
ST_UCHAR *uChar) /* ptr to value obtained
from converted ascii string */
{
ST_CHAR *retPtr;
ST_ULONG uLong = 0;
*uChar = 0;
errno = 0;
/* convert ascii string to unsigned long */
uLong = strtoul (astr, &retPtr, 10);
if (retPtr == astr || errno != 0)
return (SD_FAILURE); /* conversion error */
if (uLong > UCHAR_MAX)
/* value does not fit in range of ST_UCHAR */
return SD_FAILURE;
*uChar = (ST_UCHAR) uLong;
return SD_SUCCESS;
}
/************************************************************************/
/* asciiToSint8 */
/************************************************************************/
ST_RET asciiToSint8 (const ST_CHAR *astr, /* ascii string */
ST_INT8 *sInt8) /* ptr to value obtained
from converted ascii string */
{
ST_CHAR *retPtr;
ST_LONG sLong = 0;
*sInt8 = 0;
errno = 0;
/* convert ascii string to signed long */
sLong = strtol (astr, &retPtr, 10);
if (retPtr == astr || errno != 0)
return (SD_FAILURE); /* conversion error */
if (sLong < CHAR_MIN || sLong > CHAR_MAX)
/* value does not fit in range of ST_INT8 */
return SD_FAILURE;
*sInt8 = (ST_INT8) sLong;
return SD_SUCCESS;
}
/************************************************************************/
/* asciiToUint8 */
/************************************************************************/
ST_RET asciiToUint8 (const ST_CHAR *astr, /* ascii string */
ST_UINT8 *uInt8) /* ptr to value obtained
from converted ascii string */
{
ST_CHAR *retPtr;
ST_ULONG uLong = 0;
*uInt8 = 0;
errno = 0;
/* convert ascii string to unsigned long */
uLong = strtoul (astr, &retPtr, 10);
if (retPtr == astr || errno != 0)
return (SD_FAILURE); /* conversion error */
if (uLong > UCHAR_MAX)
/* value does not fit in range of ST_UINT8 */
return SD_FAILURE;
*uInt8 = (ST_UINT8) uLong;
return SD_SUCCESS;
}
/************************************************************************/
/* asciiToFloat */
/************************************************************************/
ST_RET asciiToFloat (const ST_CHAR *astr,
ST_FLOAT *floatNum)
{
ST_CHAR *retPtr;
ST_DOUBLE doubleNum = 0.0;
*floatNum = 0.0;
errno = 0;
/* convert ascii string to double */
doubleNum = strtod (astr, &retPtr);
if (retPtr == astr || errno != 0)
return (SD_FAILURE); /* conversion error */
if (fabs(doubleNum) > FLT_MAX)
/* value does not fit in range of ST_FLOAT */
return SD_FAILURE;
*floatNum = (ST_FLOAT) doubleNum;
return SD_SUCCESS;
}
/************************************************************************/
/* asciiToDouble */
/************************************************************************/
ST_RET asciiToDouble (const ST_CHAR *astr,
ST_DOUBLE *doubleNum)
{
ST_CHAR *retPtr;
*doubleNum = 0.0;
errno = 0;
/* convert ascii string to double */
*doubleNum = strtod (astr, &retPtr);
if (retPtr == astr || errno != 0)
return (SD_FAILURE); /* conversion error */
return SD_SUCCESS;
}
/************************************************************************/
/************************************************************************/
/* Base 10 Integer to ASCII Functions */
/************************************************************************/
static char *lToStr(long int val,char *dst, int radix);
ST_CHAR *sInt8ToAscii (ST_INT8 v, ST_CHAR *p) {lToStr ((long) v, p, -10); return p;}
ST_CHAR *uInt8ToAscii (ST_UINT8 v, ST_CHAR *p) {lToStr ((long) v, p, 10); return p;}
ST_CHAR *sInt16ToAscii (ST_INT16 v, ST_CHAR *p) {lToStr ((long) v, p, -10); return p;}
ST_CHAR *uInt16ToAscii (ST_UINT16 v, ST_CHAR *p) {lToStr ((long) v, p, 10); return p;}
ST_CHAR *sInt32ToAscii (ST_INT32 v, ST_CHAR *p) {lToStr ((long) v, p, -10); return p;}
ST_CHAR *uInt32ToAscii (ST_UINT32 v, ST_CHAR *p) {lToStr ((long) v, p, 10); return p;}
ST_CHAR *sIntToAscii (ST_INT v, ST_CHAR *p) {lToStr ((long) v, p, -10); return p;}
ST_CHAR *uIntToAscii (ST_UINT v, ST_CHAR *p) {lToStr ((long) v, p, 10); return p;}
ST_CHAR *sLongToAscii (ST_LONG v, ST_CHAR *p) {lToStr ((long) v, p, -10); return p;}
ST_CHAR *uLongToAscii (ST_ULONG v, ST_CHAR *p) {lToStr ((long) v, p, 10); return p;}
static char *lToStr(long int val,char *dst, int radix)
{
char buffer[65];
char *p;
long int new_val;
if (radix < 0) /* -10 */
{
if (val < 0)
{
*dst++ = '-';
val = -val;
}
}
p = &buffer[sizeof(buffer)-1];
*p = '\0';
new_val= (long) ((unsigned long int) val / 10);
*--p = '0'+ (char) ((unsigned long int) val - (unsigned long) new_val * 10);
val = new_val;
while (val != 0)
{
new_val=val/10;
*--p = '0' + (char) (val-new_val*10);
val= new_val;
}
while ((*dst++ = *p++) != 0) ;
return dst-1;
}
/************************************************************************/
/************************************************************************/
#if 0
#include "stime.h"
int testItoA ()
{
char dest[100];
long numMs;
double endTime;
double startTime;
int i;
startTime = sGetMsTime ();
for (i = 0; i < 100000; ++i)
sprintf (dest, "%ld", 698);
endTime = sGetMsTime ();
numMs = (long) (endTime - startTime);
printf ("\n sprintf took %ld ms", numMs);
startTime = sGetMsTime ();
for (i = 0; i < 100000; ++i)
ltoa (698, dest, 10);
endTime = sGetMsTime ();
numMs = (long) (endTime - startTime);
printf ("\n ltoa took %ld ms", numMs);
startTime = sGetMsTime ();
for (i = 0; i < 100000; ++i)
lToStr (698, dest);
endTime = sGetMsTime ();
numMs = (long) (endTime - startTime);
printf ("\n lToStr took %ld ms", numMs);
lToStr (0, dest);
if (strcmp (dest, "0"))
printf ("\nError in lToStr (0, dest);");
lToStr (-1, dest);
if (strcmp (dest, "-1"))
printf ("\nError in lToStr (-1, dest);");
lToStr (1, dest);
if (strcmp (dest, "1"))
printf ("\nError in lToStr (1, dest);");
sInt16ToAscii (SHRT_MIN, dest);
if (strcmp (dest, "-32768"))
printf ("\nError in sInt16ToAscii (SHRT_MIN, dest);");
sInt16ToAscii (SHRT_MAX, dest);
if (strcmp (dest, "32767"))
printf ("\nError in sInt16ToAscii (SHRT_MAX, dest);");
uInt16ToAscii (USHRT_MAX, dest);
if (strcmp (dest, "65535"))
printf ("\nError in sUint16ToAscii (USHRT_MAX, dest);");
sIntToAscii (INT_MIN, dest);
if (strcmp (dest, "-2147483648"))
printf ("\nError in sIntToAscii (INT_MIN, dest);");
sIntToAscii (INT_MAX, dest);
if (strcmp (dest, "2147483647"))
printf ("\nError in sIntToAscii (INT_MAX, dest);");
uIntToAscii (UINT_MAX, dest);
if (strcmp (dest, "0xffffffff"))
printf ("\nError in sUintToAscii (UINT_MAX, dest);");
sLongToAscii (LONG_MIN, dest);
if (strcmp (dest, "-2147483648"))
printf ("\nError in sIntToAscii (INT_MIN, dest);");
sLongToAscii (LONG_MAX, dest);
if (strcmp (dest, "2147483647"))
printf ("\nError in sIntToAscii (INT_MAX, dest);");
uLongToAscii (ULONG_MAX, dest);
if (strcmp (dest, "4294967295"))
printf ("\nError in sUintToAscii (UINT_MAX, dest);");
}
#endif
/************************************************************************/
/* getKeywordFromFile */
/*----------------------------------------------------------------------*/
/* Function to check if given keyword is found in a specified text file.*/
/* When found, keyword value (string) is copied to user buffer valBuf. */
/* This function assumes that there is one keyword per line in the file */
/* in the form: */
/* keyword=val */
/* Where val is an int, long, string, etc. */
/* keywordStr should include the '=' char. */
/* Line length is limited to 255 bytes. */
/* Any NL or CR characters are eliminated from the end of line. */
/* Parameters: */
/* ST_CHAR *fileStr file to open */
/* ST_CHAR *keywordStr keyword to look for in file */
/* ST_CHAR *valBuf ptr where to put keyword value */
/* ST_UINT valBufLen len of buffer for the value. */
/* Return: */
/* SD_TRUE if keyword found. */
/* SD_FALSE otherwise */
/************************************************************************/
ST_BOOLEAN getKeywordFromFile (ST_CHAR *fileStr, ST_CHAR *keywordStr,
ST_CHAR *valBuf, ST_UINT valBufLen)
{
ST_BOOLEAN ret = SD_FALSE;
ST_CHAR lineBuf[256];
ST_CHAR *keywordPtr = NULL; /* set if keywordStr found */
FILE *fd = NULL;
ST_INT i;
ST_INT copyLen;
/* make sure we got some valid parameters */
if (!fileStr || strlen(fileStr) == 0)
return (ret);
if (!keywordStr || strlen(keywordStr) == 0)
return (ret);
if (!valBuf || valBufLen == 0 || valBufLen >= sizeof(lineBuf))
return (ret);
/* open and read the file line by line */
if ((fd = fopen (fileStr, "r")) != NULL)
{
memset (lineBuf, 0, sizeof(lineBuf));
while (fgets(lineBuf, sizeof(lineBuf)-1, fd) != NULL)
{
/* eliminate any NL or CR characters from the end of line */
for (i=0; i<sizeof(lineBuf); i++)
{
if (lineBuf[i] == '\n' || lineBuf[i] == '\r')
lineBuf[i] = 0;
}
/* find the keywordStr in lineBuf */
keywordPtr = strstr(lineBuf, keywordStr);
if (keywordPtr)
{
copyLen = min (valBufLen-1, strlen(lineBuf)-strlen(keywordStr));
memcpy (valBuf, &keywordPtr[strlen(keywordStr)], copyLen);
valBuf[copyLen] = 0; /* NULL terminate the value */
ret = SD_TRUE;
}
/* reset for next line */
memset (lineBuf, 0, sizeof(lineBuf));
}
fclose (fd);
}
return (ret);
}
/************************************************************************/
/* get_next_string */
/* Return pointer to next string in input buffer, separated by */
/* delimiters (string may be surrounded by "double quotes"). */
/* ARGUMENTS: */
/* ptrptr - address of current ptr. Current ptr changed by this funct.*/
/* delimiters - set of delimiter chars (like strtok or strpbrk). */
/* RETURNS: ptr to string found, NULL on error or end of input string.*/
/************************************************************************/
ST_CHAR *get_next_string (ST_CHAR **ptrptr, ST_CHAR *delimiters)
{
ST_CHAR *curptr;
ST_CHAR *string;
ST_CHAR *next_delimiter;
/* If (*ptrptr==NULL), can't do anything. Just return NULL. */
/* May often happen if last call failed or hit end of input buffer. */
if (*ptrptr == NULL)
string = NULL;
else
{
curptr = *ptrptr; /* copy to local var for readability */
/* renxiaobao <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
while (*curptr == ' ' || *curptr == ','|| *curptr == '\t'|| *curptr == '\n')
{
curptr++;
}
/* add end*/
/* if next char is double quote, get up to next double quote */
if (*curptr == '\"')
{
curptr++; /* point after starting quote */
string = curptr;
curptr = strpbrk (curptr, "\""); /* find ending quote */
/* NOTE: curptr should now point to ending quote, but */
/* it may be NULL, if ending quote not found. */
if (curptr)
{
*curptr = '\0'; /* replace ending quote with NULL */
curptr++; /* point after ending quote */
}
if (curptr)
{ /* make sure next character is delimiter, then skip it. */
next_delimiter = strpbrk (curptr, delimiters); /* find next delimiter */
if (next_delimiter != curptr)
{
SLOGALWAYS1 ("get_next_string ERROR: '%c' after ending quote. Expecting delimiter.", *curptr);
string = NULL; /* error */
curptr = NULL; /* error */
}
else
curptr++; /* skip this delimiter */
}
}
else if (*curptr == '\0')
{ /* no more strings */
string = NULL;
curptr = NULL;
}
else
{
string = curptr;
curptr = strpbrk (curptr, delimiters); /* find next delimiter */
/* NOTE: curptr should now point to ending delimiter, but */
/* it may be NULL, if expected delimiter not found. */
if (curptr)
{
*curptr = '\0'; /* replace delimiter with NULL */
curptr++; /* point after delimiter */
}
}
*ptrptr = curptr; /* NULL on any error OR end of input string */
}
return (string); /* return ptr to string (NULL on any error) */
}

1964
mmslib/util/sx_axs4d.c Normal file

File diff suppressed because it is too large Load Diff

2601
mmslib/util/sx_data.c Normal file

File diff suppressed because it is too large Load Diff

2520
mmslib/util/sx_dec.c Normal file

File diff suppressed because it is too large Load Diff

1344
mmslib/util/sx_enc.c Normal file

File diff suppressed because it is too large Load Diff

2748
mmslib/util/time_str.c Normal file

File diff suppressed because it is too large Load Diff