summaryrefslogtreecommitdiff
path: root/mbglib/common/mbgutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'mbglib/common/mbgutil.c')
-rwxr-xr-xmbglib/common/mbgutil.c462
1 files changed, 286 insertions, 176 deletions
diff --git a/mbglib/common/mbgutil.c b/mbglib/common/mbgutil.c
index edc41b4..d3cb946 100755
--- a/mbglib/common/mbgutil.c
+++ b/mbglib/common/mbgutil.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
- * $Id: mbgutil.c 1.6 2012/10/15 13:12:17 martin REL_M $
+ * $Id: mbgutil.c 1.6.1.18 2016/07/22 09:57:11 martin TEST $
*
* Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
*
@@ -10,6 +10,30 @@
*
* -----------------------------------------------------------------------
* $Log: mbgutil.c $
+ * Revision 1.6.1.18 2016/07/22 09:57:11 martin
+ * Quieted some compiler warninges.
+ * Revision 1.6.1.17 2016/07/15 14:09:48 martin
+ * Use functions from new module timeutil.
+ * Revision 1.6.1.16 2016/04/26 09:23:36 martin
+ * Revision 1.6.1.15 2016/03/16 11:46:34Z martin
+ * *** empty log message ***
+ * Revision 1.6.1.14 2015/12/01 11:36:25 martin
+ * *** empty log message ***
+ * Revision 1.6.1.13 2015/11/24 15:44:55 martin
+ * Revision 1.6.1.12 2015/11/20 16:30:41Z martin
+ * Revision 1.6.1.11 2015/11/02 10:12:28Z martin
+ * *** empty log message ***
+ * Revision 1.6.1.10 2015/10/30 11:36:54 martin
+ * Revision 1.6.1.9 2015/09/08 10:37:02Z martin
+ * Revision 1.6.1.8 2015/08/27 16:17:27Z martin
+ * Use safe string functions from str_util.c.
+ * Revision 1.6.1.7 2014/05/27 11:32:47 martin
+ * Revision 1.6.1.6 2014/05/27 11:26:24 martin
+ * Revision 1.6.1.5 2014/03/13 16:04:12 martin
+ * Revision 1.6.1.4 2014/03/13 15:45:36 martin
+ * Revision 1.6.1.3 2014/03/13 14:31:52Z martin
+ * Revision 1.6.1.2 2013/10/23 10:40:53Z martin
+ * Revision 1.6.1.1 2013/10/22 10:05:55 martin
* Revision 1.6 2012/10/15 13:12:17 martin
* Fixed build under DOS.
* Fixed format/type mismatch when printing UTC offset.
@@ -35,12 +59,17 @@
#include <mbgutil.h>
#undef _MBGUTIL
+#include <cfg_hlp.h>
+#include <mbgerror.h>
#include <pcpsutil.h>
-#include <pcpslstr.h>
+#include <charcode.h>
#include <pcpsdev.h>
+#include <str_util.h>
+#include <qsdefs.h>
#include <stdio.h>
#include <time.h>
+#include <limits.h>
// required at least for Linux:
#include <stdarg.h>
@@ -60,32 +89,32 @@ static int mbg_date_time_dist = 2;
static int mbg_pos_dist = 2;
static uint16_t mbg_year_lim = 1980;
+static const char str_inv_cnv[] = "(invalid conversion)";
+
+// The size_t type can eventually be larger than an int type.
+// However, some snprintf-like functions expect a size_t value
+// to specify the buffer size, but just return an int value.
+// So we take care that at least the return value is limited
+// to MAXINT.
#if defined( MBG_TGT_WIN32 )
- #define mbg_vsnprintf _vsnprintf
+ #define _int_from_size_t( _n ) \
+ ( ( (_n) > INT_MAX ) ? INT_MAX : (int) (_n) )
#else
- #define mbg_vsnprintf vsnprintf
-#endif
-
-
-#if defined( MBG_TGT_DOS )
-
-static /*HDR*/
-int vsnprintf( char *s, int max_len, const char *fmt, va_list arg_list )
-{
- return vsprintf( s, fmt, arg_list );
-
-} // vsnprintf
-
+ #define _int_from_size_t( _n ) (_n)
#endif
/*HDR*/
+/**
+ * @brief Get the DLL/shared library's version code
+ *
+ * @return The version code at which the library was built
+ */
_MBG_API_ATTR int _MBG_API mbgutil_get_version( void )
{
-
return MBGUTIL_VERSION;
} // mbgutil_get_version
@@ -93,54 +122,58 @@ _MBG_API_ATTR int _MBG_API mbgutil_get_version( void )
/*HDR*/
+/**
+ * @brief Check the DLL/shared library's compatibility
+ *
+ * @param header_version Version code defined in the header file when the application is built
+ *
+ * @return ::MBG_SUCCESS if compatible, else ::MBG_ERR_LIB_NOT_COMPATIBLE
+ */
_MBG_API_ATTR int _MBG_API mbgutil_check_version( int header_version )
{
if ( header_version >= MBGUTIL_COMPAT_VERSION )
- return PCPS_SUCCESS;
+ return MBG_SUCCESS;
- return -1;
+ return MBG_ERR_LIB_NOT_COMPATIBLE;
} // mbgutil_check_version
-// We have our own version of snprintf() since under Windows
-// _snprintf(), returns -1 and does not write a terminating 0
-// if the output exceeds the buffer size.
-//
-// This function terminates the output string properly. However,
-// the maximum return value is (max_len - 1), so the function
-// can not be used to determine the buffer size that would be
-// required for an untruncated string.
-
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_snprintf( char *s, size_t max_len, const char * fmt, ... )
+/**
+ * @brief A portable, safe implementation of snprintf()
+ *
+ * For a detailed description see ::vsnprintf_safe
+ *
+ * @param s pointer to the output buffer
+ * @param max_len size of the output buffer
+ * @param fmt format string according to subsequent parameters
+ * @param ... variable argument list according to the format string
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ *
+ * @see ::vsnprintf_safe
+ * @see ::snprintf_safe
+ */
+_MBG_API_ATTR int __attribute__( ( format( printf, 3, 4 ) ) )
+_MBG_API mbg_snprintf( char *s, size_t max_len, const char * fmt, ... )
{
- int n;
-
+ size_t n;
va_list ap;
- va_start( ap, fmt );
-
- n = mbg_vsnprintf( s, max_len, fmt, ap );
-
- va_end( ap );
-
+ // TODO: size_t can be larger than int, so what happens if
+ // a very long string is written to the buffer and the number
+ // of bytes written exceeds MAXINT, in which case the number
+ // can't be returned?
- #if defined( MBG_TGT_WIN32 )
-
- // Terminate the output string properly under Windows.
- // For other targets assume the POSIX version is available.
- if ( n < 0 || n >= (int) max_len )
- {
- n = max_len - 1;
- s[n] = 0;
- }
+ va_start( ap, fmt );
- #endif
+ n = vsnprintf_safe( s, max_len, fmt, ap );
+ va_end( ap );
- return n;
+ return _int_from_size_t( n );
} // mbg_snprintf
@@ -149,14 +182,26 @@ _MBG_API_ATTR int _MBG_API mbg_snprintf( char *s, size_t max_len, const char * f
/*HDR*/
_MBG_API_ATTR int _MBG_API mbg_strncpy( char *s, size_t max_len, const char *src )
{
- //##++ This could be coded more efficiently
- return mbg_snprintf( s, max_len, "%s", src );
+ size_t n = sn_cpy_str_safe( s, max_len, src );
+ return _int_from_size_t( n );
} // mbg_strncpy
/*HDR*/
+/**
+ * @brief Write a character multiple times to a string buffer
+ *
+ * Append a terminating 0 to the buffer.
+ *
+ * @param s pointer to the output buffer
+ * @param max_len size of the output buffer
+ * @param c the character to write to the output buffer
+ * @param n the number of characters to write to the output buffer
+ *
+ * @return the number of characters written to the output buffer, except the terminating 0
+ */
_MBG_API_ATTR int _MBG_API mbg_strchar( char *s, size_t max_len, char c, size_t n )
{
size_t i;
@@ -168,48 +213,54 @@ _MBG_API_ATTR int _MBG_API mbg_strchar( char *s, size_t max_len, char c, size_t
if ( i >= max_len )
break;
+ if ( i >= ( INT_MAX - 1 ) )
+ break;
+
s[i] = c;
}
s[i] = 0;
- return i;
+ return (int) i;
} // mbg_strchar
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_date_short( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_date_short( char *s, int max_len,
int mday, int month )
{
- return mbg_snprintf( s, max_len, "%02u.%02u.", mday, month );
-
+ size_t n = snprintf_safe( s, max_len, "%02u.%02u.", mday, month );
+ return _int_from_size_t( n );
+
} // mbg_str_date_short
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_date( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_date( char *s, int max_len,
int mday, int month, int year )
{
- int n = mbg_str_date_short( s, max_len, mday, month );
- n += mbg_snprintf( s + n, max_len - n, "%04u",
- ( year < 256 ) ?
- pcps_exp_year( (uint8_t) year, mbg_year_lim ) :
- year
- );
- return n;
+ size_t n = mbg_str_date_short( s, max_len, mday, month );
+
+ n += snprintf_safe( &s[n], max_len - n, "%04u",
+ ( year < 256 ) ?
+ pcps_exp_year( (uint8_t) year, mbg_year_lim ) :
+ year );
+
+ return _int_from_size_t( n );
} // mbg_str_date
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_time_short( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_time_short( char *s, int max_len,
int hour, int min )
{
- return mbg_snprintf( s, max_len, "%2u:%02u", hour, min );
+ size_t n = snprintf_safe( s, max_len, "%2u:%02u", hour, min );
+ return _int_from_size_t( n );
} // mbg_str_time_short
@@ -219,11 +270,11 @@ _MBG_API_ATTR int _MBG_API mbg_str_time_short( char *s, int max_len,
_MBG_API_ATTR int _MBG_API mbg_str_time( char *s, int max_len,
int hour, int min, int sec )
{
- int n = mbg_str_time_short( s, max_len, hour, min );
+ size_t n = mbg_str_time_short( s, max_len, hour, min );
- n += mbg_snprintf( s + n, max_len - n, ":%02u", sec );
+ n += snprintf_safe( &s[n], max_len - n, ":%02u", sec );
- return n;
+ return _int_from_size_t( n );
} // mbg_str_time
@@ -233,11 +284,11 @@ _MBG_API_ATTR int _MBG_API mbg_str_time( char *s, int max_len,
_MBG_API_ATTR int _MBG_API mbg_str_time_long( char *s, int max_len,
int hour, int min, int sec, int sec100 )
{
- int n = mbg_str_time( s, max_len, hour, min, sec );
+ size_t n = mbg_str_time( s, max_len, hour, min, sec );
- n += mbg_snprintf( s + n, max_len - n, ".%02u", sec100 );
+ n += snprintf_safe( &s[n], max_len - n, ".%02u", sec100 );
- return n;
+ return _int_from_size_t( n );
} // mbg_str_time_long
@@ -247,31 +298,33 @@ _MBG_API_ATTR int _MBG_API mbg_str_time_long( char *s, int max_len,
_MBG_API_ATTR int _MBG_API mbg_str_tm_gps_date_time( char *s, int max_len,
const TM_GPS *pt )
{
- int n = mbg_str_date( s, max_len, pt->mday, pt->month, pt->year );
- n += mbg_strchar( s + n, max_len - n, ' ', mbg_date_time_dist );
- n += mbg_str_time( s + n, max_len - n, pt->hour, pt->min, pt->sec );
+ size_t n = mbg_str_date( s, max_len, pt->mday, pt->month, pt->year );
+ n += mbg_strchar( &s[n], max_len - n, ' ', mbg_date_time_dist );
+ n += mbg_str_time( &s[n], max_len - _int_from_size_t( n ), pt->hour, pt->min, pt->sec );
- return n;
+ return _int_from_size_t( n );
} // mbg_str_tm_gps_date_time
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_date_short( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_date_short( char *s, int max_len,
const PCPS_TIME *pt )
{
- return mbg_str_date_short( s, max_len, pt->mday, pt->month );
+ size_t n = mbg_str_date_short( s, max_len, pt->mday, pt->month );
+ return _int_from_size_t( n );
} // mbg_str_pcps_date_short
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_date( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_date( char *s, int max_len,
const PCPS_TIME *pt )
{
- return mbg_str_date( s, max_len, pt->mday, pt->month, pt->year );
+ size_t n = mbg_str_date( s, max_len, pt->mday, pt->month, pt->year );
+ return _int_from_size_t( n );
} // mbg_str_pcps_date
@@ -281,7 +334,8 @@ _MBG_API_ATTR int _MBG_API mbg_str_pcps_date( char *s, int max_len,
_MBG_API_ATTR int _MBG_API mbg_str_pcps_time_short( char *s, int max_len,
const PCPS_TIME *pt )
{
- return mbg_str_time_short( s, max_len, pt->hour, pt->min );
+ size_t n = mbg_str_time_short( s, max_len, pt->hour, pt->min );
+ return _int_from_size_t( n );
} // mbg_str_pcps_time_short
@@ -291,7 +345,8 @@ _MBG_API_ATTR int _MBG_API mbg_str_pcps_time_short( char *s, int max_len,
_MBG_API_ATTR int _MBG_API mbg_str_pcps_time( char *s, int max_len,
const PCPS_TIME *pt )
{
- return mbg_str_time( s, max_len, pt->hour, pt->min, pt->sec );
+ size_t n = mbg_str_time( s, max_len, pt->hour, pt->min, pt->sec );
+ return _int_from_size_t( n );
} // mbg_str_pcps_time
@@ -301,60 +356,77 @@ _MBG_API_ATTR int _MBG_API mbg_str_pcps_time( char *s, int max_len,
_MBG_API_ATTR int _MBG_API mbg_str_pcps_time_long( char *s, int max_len,
const PCPS_TIME *pt )
{
- return mbg_str_time_long( s, max_len, pt->hour, pt->min, pt->sec, pt->sec100 );
+ size_t n = mbg_str_time_long( s, max_len, pt->hour, pt->min, pt->sec, pt->sec100 );
+ return _int_from_size_t( n );
} // mbg_str_pcps_time_long
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_date_time( char *s, int max_len,
- const PCPS_TIME *pt,
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_date_time( char *s, int max_len,
+ const PCPS_TIME *pt,
const char *tz_str )
{
- int n = mbg_str_pcps_date( s, max_len, pt );
- n += mbg_strchar( s + n, max_len - n, ' ', mbg_date_time_dist );
- n += mbg_str_pcps_time( s + n, max_len - n, pt );
+ size_t n = mbg_str_pcps_date( s, max_len, pt );
+ n += mbg_strchar( &s[n], max_len - n, ' ', mbg_date_time_dist );
+ n += mbg_str_pcps_time( &s[n], max_len - _int_from_size_t( n ), pt );
+
+ return _int_from_size_t( n );
- return n;
-
} // mbg_str_pcps_date_time
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date( char *s, int max_len,
uint32_t sec )
{
- time_t t = sec;
- struct tm tm = *gmtime( &t );
- return mbg_str_date( s, max_len, tm.tm_mday, tm.tm_mon + 1, tm.tm_year );
+ struct tm tm = { 0 };
+ time_t t = cvt_to_time_t( sec );
+ int rc = mbg_gmtime( &tm, &t );
+
+ return mbg_rc_is_success( rc ) ?
+ mbg_str_date( s, max_len, tm.tm_mday, tm.tm_mon + 1, tm.tm_year ) :
+ sn_cpy_str_safe( s, max_len, str_inv_cnv );
} // mbg_str_pcps_hr_date
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time( char *s, int max_len,
uint32_t sec )
{
- time_t t = sec;
- struct tm tm = *gmtime( &t );
- return mbg_str_time( s, max_len, tm.tm_hour, tm.tm_min, tm.tm_sec );
+ struct tm tm = { 0 };
+ time_t t = cvt_to_time_t( sec );
+ int rc = mbg_gmtime( &tm, &t );
+
+ return mbg_rc_is_success( rc ) ?
+ mbg_str_time( s, max_len, tm.tm_hour, tm.tm_min, tm.tm_sec ) :
+ sn_cpy_str_safe( s, max_len, str_inv_cnv );
} // mbg_str_pcps_hr_time
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date_time_utc( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date_time_utc( char *s, int max_len,
const PCPS_HR_TIME *pt )
{
- time_t t = pt->tstamp.sec;
- struct tm tm = *gmtime( &t );
- int n = mbg_str_date( s, max_len, tm.tm_mday , tm.tm_mon + 1, tm.tm_year );
- n += mbg_strchar( s + n, max_len - n, ' ', mbg_date_time_dist );
- n += mbg_str_time( s + n, max_len - n, tm.tm_hour, tm.tm_min, tm.tm_sec );
+ struct tm tm = { 0 };
+ int n = 0;
+ time_t t = cvt_to_time_t( pt->tstamp.sec );
+ int rc = mbg_gmtime( &tm, &t );
+
+ if ( mbg_rc_is_success( rc ) )
+ {
+ n = mbg_str_date( s, max_len, tm.tm_mday , tm.tm_mon + 1, tm.tm_year );
+ n += mbg_strchar( &s[n], max_len - n, ' ', mbg_date_time_dist );
+ n += mbg_str_time( &s[n], max_len - n, tm.tm_hour, tm.tm_min, tm.tm_sec );
+ }
+ else
+ n = sn_cpy_str_safe( s, max_len, str_inv_cnv );
return n;
@@ -363,14 +435,23 @@ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date_time_utc( char *s, int max_len,
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date_time_loc( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date_time_loc( char *s, int max_len,
const PCPS_HR_TIME *pt )
{
- time_t t = pt->tstamp.sec + pt->utc_offs;
- struct tm tm = *gmtime( &t );
- int n = mbg_str_date( s, max_len, tm.tm_mday , tm.tm_mon + 1, tm.tm_year );
- n += mbg_strchar( s + n, max_len - n, ' ', mbg_date_time_dist );
- n += mbg_str_time( s + n, max_len - n, tm.tm_hour, tm.tm_min, tm.tm_sec );
+ struct tm tm = { 0 };
+ int n = 0;
+ long l = (long) pt->tstamp.sec + pt->utc_offs;
+ time_t t = cvt_to_time_t( l );
+ int rc = mbg_gmtime( &tm, &t );
+
+ if ( mbg_rc_is_success( rc ) )
+ {
+ n = mbg_str_date( s, max_len, tm.tm_mday , tm.tm_mon + 1, tm.tm_year );
+ n += mbg_strchar( &s[n], max_len - n, ' ', mbg_date_time_dist );
+ n += mbg_str_time( &s[n], max_len - n, tm.tm_hour, tm.tm_min, tm.tm_sec );
+ }
+ else
+ n = sn_cpy_str_safe( s, max_len, str_inv_cnv );
return n;
@@ -379,40 +460,41 @@ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_date_time_loc( char *s, int max_len,
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_frac( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_frac( char *s, int max_len,
uint32_t frac )
{
- return mbg_snprintf( s, max_len, PCPS_HRT_FRAC_SCALE_FMT,
- frac_sec_from_bin( frac, PCPS_HRT_FRAC_SCALE ) );
+ size_t n = snprintf_safe( s, max_len, PCPS_HRT_FRAC_SCALE_FMT,
+ (ulong) frac_sec_from_bin( frac, PCPS_HRT_FRAC_SCALE ) );
+ return _int_from_size_t( n );
} // mbg_str_pcps_hr_time_frac
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_offs( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_offs( char *s, int max_len,
const PCPS_HR_TIME *pt,
const char *info )
{
- int n = mbg_snprintf( s, max_len, "%s", info );
+ size_t n = snprintf_safe( s, max_len, "%s", info );
if ( pt->utc_offs )
{
ldiv_t ldt = ldiv( labs( pt->utc_offs ) / 60, 60 );
- n += mbg_snprintf( s + n, max_len - n, "%c%02lu:%02luh",
- ( pt->utc_offs < 0 ) ? '-' : '+',
- ldt.quot, ldt.rem );
+ n += snprintf_safe( &s[n], max_len - n, "%c%02lu:%02luh",
+ ( pt->utc_offs < 0 ) ? '-' : '+',
+ ldt.quot, ldt.rem );
}
- return n;
+ return _int_from_size_t( n );
} // mbg_str_pcps_hr_time_offs
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_utc( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_utc( char *s, int max_len,
const PCPS_HR_TIME *pt )
{
int n = mbg_str_pcps_hr_date_time_utc( s, max_len, pt );
@@ -420,7 +502,7 @@ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_utc( char *s, int max_len,
if ( n < ( max_len - 1 ) )
{
s[n++] = '.';
- n += mbg_str_pcps_hr_time_frac( s + n, max_len - n, pt->tstamp.frac );
+ n += mbg_str_pcps_hr_time_frac( &s[n], max_len - n, pt->tstamp.frac );
}
return n;
@@ -430,7 +512,7 @@ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_utc( char *s, int max_len,
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_loc( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_loc( char *s, int max_len,
const PCPS_HR_TIME *pt )
{
int n = mbg_str_pcps_hr_date_time_loc( s, max_len, pt );
@@ -438,7 +520,7 @@ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_loc( char *s, int max_len,
if ( n < ( max_len - 1 ) )
{
s[n++] = '.';
- n += mbg_str_pcps_hr_time_frac( s + n, max_len - n, pt->tstamp.frac );
+ n += mbg_str_pcps_hr_time_frac( &s[n], max_len - n, pt->tstamp.frac );
}
if ( n < ( max_len - 1 ) )
@@ -452,7 +534,7 @@ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_loc( char *s, int max_len,
cp = "GPS";
s[n++] = ' ';
- n += mbg_str_pcps_hr_time_offs( s + n, max_len - n, pt, cp );
+ n += mbg_str_pcps_hr_time_offs( &s[n], max_len - n, pt, cp );
}
return n;
@@ -462,53 +544,51 @@ _MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_tstamp_loc( char *s, int max_len,
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_tstamp_raw( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_tstamp_raw( char *s, int max_len,
const PCPS_TIME_STAMP *pt )
{
- return mbg_snprintf( s, max_len, "%08lX.%08lX", pt->sec, pt->frac );
+ size_t n = snprintf_safe( s, max_len, "%08lX.%08lX", (ulong) pt->sec, (ulong) pt->frac );
+ return _int_from_size_t( n );
} // mbg_str_pcps_tstamp_raw
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_raw( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_pcps_hr_time_raw( char *s, int max_len,
const PCPS_HR_TIME *pt )
{
- int n = mbg_str_pcps_tstamp_raw( s, max_len, &pt->tstamp );
- n += mbg_str_pcps_hr_time_offs( s + n, max_len - n, pt, ", Loc: " );
- n += mbg_snprintf( s + n, max_len - n, ", st: 0x%04X", pt->status );
+ size_t n = mbg_str_pcps_tstamp_raw( s, max_len, &pt->tstamp );
+ n += mbg_str_pcps_hr_time_offs( &s[n], max_len - _int_from_size_t( n ), pt, ", Loc: " );
+ n += snprintf_safe( &s[n], max_len - n, ", st: 0x%04X", pt->status );
+
+ return _int_from_size_t( n );
- return n;
-
} // mbg_str_pcps_hr_time_raw
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_ucap( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_ucap( char *s, int max_len,
const PCPS_HR_TIME *pt )
{
- int n = mbg_snprintf( s, max_len, "CAP%u: ", pt->signal );
- n += mbg_str_pcps_hr_tstamp_loc( s + n, max_len - n, pt );
+ size_t n = snprintf_safe( s, max_len, "CAP%u: ", pt->signal );
+ n += mbg_str_pcps_hr_tstamp_loc( &s[n], max_len - _int_from_size_t( n ), pt );
+
+ return _int_from_size_t( n );
- return n;
-
} // mbg_str_ucap
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pos_dms( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_pos_dms( char *s, int max_len,
const DMS *pdms, int prec )
{
- return mbg_snprintf( s, max_len, "%c %i" DEG "%02i'%02.*f\"",
- pdms->prefix,
- pdms->deg,
- pdms->min,
- prec,
- pdms->sec
- );
+ size_t n = snprintf_safe( s, max_len, "%c %i" DEG "%02i'%02.*f\"",
+ pdms->prefix, pdms->deg, pdms->min,
+ prec, pdms->sec );
+ return _int_from_size_t( n );
} // mbg_str_pos_dms
@@ -517,14 +597,15 @@ _MBG_API_ATTR int _MBG_API mbg_str_pos_dms( char *s, int max_len,
/*HDR*/
_MBG_API_ATTR int _MBG_API mbg_str_pos_alt( char *s, int max_len, double alt )
{
- return mbg_snprintf( s, max_len, "%.0fm", alt );
+ size_t n = snprintf_safe( s, max_len, "%.0fm", alt );
+ return _int_from_size_t( n );
} // mbg_str_pos_alt
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_pos( char *s, int max_len,
+_MBG_API_ATTR int _MBG_API mbg_str_pos( char *s, int max_len,
const POS *ppos, int prec )
{
int n;
@@ -532,15 +613,15 @@ _MBG_API_ATTR int _MBG_API mbg_str_pos( char *s, int max_len,
if ( ppos->lla[LON] || ppos->lla[LAT] || ppos->lla[ALT] )
{
n = mbg_str_pos_dms( s, max_len, &ppos->latitude, prec );
- n += mbg_strchar( s + n, max_len - n, ',', 1 );
- n += mbg_strchar( s + n, max_len - n, ' ', mbg_pos_dist );
- n += mbg_str_pos_dms( s + n, max_len - n, &ppos->longitude, prec );
- n += mbg_strchar( s + n, max_len - n, ',', 1 );
- n += mbg_strchar( s + n, max_len - n, ' ', mbg_pos_dist );
- n += mbg_str_pos_alt( s + n, max_len - n, ppos->lla[ALT] );
+ n += mbg_strchar( &s[n], max_len - n, ',', 1 );
+ n += mbg_strchar( &s[n], max_len - n, ' ', mbg_pos_dist );
+ n += mbg_str_pos_dms( &s[n], max_len - n, &ppos->longitude, prec );
+ n += mbg_strchar( &s[n], max_len - n, ',', 1 );
+ n += mbg_strchar( &s[n], max_len - n, ' ', mbg_pos_dist );
+ n += mbg_str_pos_alt( &s[n], max_len - n, ppos->lla[ALT] );
}
else
- n = mbg_strncpy( s, max_len, "N/A" );
+ n = mbg_strncpy( s, max_len, str_not_avail );
return n;
@@ -549,53 +630,82 @@ _MBG_API_ATTR int _MBG_API mbg_str_pos( char *s, int max_len,
/*HDR*/
-_MBG_API_ATTR int _MBG_API mbg_str_dev_name( char *s, int max_len, const char *short_name,
+_MBG_API_ATTR int _MBG_API mbg_str_dev_name( char *s, int max_len, const char *short_name,
uint16_t fw_rev_num, PCI_ASIC_VERSION asic_version_num )
{
- #define HW_NAME_SZ PCPS_CLOCK_NAME_SZ+PCPS_SN_SIZE+1
+ #define HW_NAME_SZ ( PCPS_CLOCK_NAME_SZ + PCPS_SN_SIZE + 1 )
- char model_code[HW_NAME_SZ];
- PCPS_SN_STR sernum;
+ char model_code[HW_NAME_SZ] = { 0 };
+ PCPS_SN_STR sernum = { 0 };
unsigned int i = 0;
- int n = 0;
+ size_t n = 0;
+ size_t l = strlen( short_name );
- memset( model_code, 0, sizeof( model_code ) );
- memset( sernum, 0, sizeof( sernum ) );
-
- if ( strlen( short_name ) > 0 )
+ if ( l > 0 )
{
- if ( strstr( short_name, "COM") )
- return mbg_snprintf(s, max_len,"%s", short_name);
+ // For serial port string specifies we just copy
+ // the short_name.
+ if ( device_id_is_serial( short_name ) )
+ {
+ n = sn_cpy_str_safe( s, max_len, short_name );
+ goto out;
+ }
+
+ // If the short_name has more than HW_NAME_SZ characters
+ // then we have to reduce the maximum length.
+ // For bus level device, the short_name usually consists of
+ // the model name, followed by an underscore '_', followed
+ // by the serial number, e.g. "PZF180PEX_046411000030".
+ if ( HW_NAME_SZ < l )
+ l = HW_NAME_SZ;
- for ( i = 0; ( i < HW_NAME_SZ ) && ( i < strlen( short_name ) ); i++ )
+ for ( i = 0; i < l; i++ )
{
if ( short_name[i] == '_' )
{
i++;
break;
}
+
model_code[i] = short_name[i];
}
- strncpy( sernum, &short_name[i], PCPS_SN_SIZE-1 );
- if ( sernum[12] == ' ' )
- sernum[12] = '\0';
+ strncpy_safe( sernum, &short_name[i], sizeof( sernum ) );
+
+ //### TODO
+ // Legal serial numbers have MBG_GRP_SERNUM_LEN characters, which is
+ // less than the maximum length of a PCPS_SN_STR type string.
+ // Do we really have to check and truncate the PCPS_SN_STR sernum?
+ if ( sernum[MBG_GRP_SERNUM_LEN] == ' ' )
+ sernum[MBG_GRP_SERNUM_LEN] = '\0';
}
- n = mbg_snprintf( s, max_len, "%s, S/N %s", model_code, sernum );
+ n = snprintf_safe( s, max_len, "%s, S/N %s", model_code, sernum );
- if ( fw_rev_num > 0 )
- n += mbg_snprintf( &s[n], max_len," (FW v%X.%02X", fw_rev_num>>8, fw_rev_num & 0x00FF );
+ if ( fw_rev_num || asic_version_num )
+ n += sn_cpy_str_safe( &s[n], max_len - n, " (" );
- if ( asic_version_num > 0 )
+ if ( fw_rev_num )
{
- mbg_snprintf( &s[n], max_len," / ASIC v%d.%02d)", _convert_asic_version_number( asic_version_num ) >> 8,
- ( _convert_asic_version_number( asic_version_num ) ) & 0xFF );
+ n += snprintf_safe( &s[n], max_len - n, "FW v%X.%02X",
+ fw_rev_num >> 8, fw_rev_num & 0xFF );
+ // Append a separator if ASIC version will follow.
+ if ( asic_version_num )
+ n += sn_cpy_str_safe( &s[n], max_len - n, " / " );
}
- else
- mbg_snprintf( &s[n], max_len,")" );
- return strlen(s);
+ if ( asic_version_num )
+ {
+ n += snprintf_safe( &s[n], max_len - n, "ASIC v%d.%02d",
+ _convert_asic_version_number( asic_version_num ) >> 8,
+ _convert_asic_version_number( asic_version_num ) & 0xFF );
+ }
+
+ if ( fw_rev_num || asic_version_num )
+ n += sn_cpy_str_safe( &s[n], max_len - n, ")" );
+
+out:
+ return _int_from_size_t( n );
} // mbg_str_dev_name