LCOV - code coverage report
Current view: top level - home/lbartoletti/qgis/external/nmea - tok.c (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 0 129 0.0 %
Date: 2021-03-26 12:19:53 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            : * Copyright Tim (xtimor@gmail.com)
       3                 :            : *
       4                 :            : * NMEA library is free software; you can redistribute it and/or modify
       5                 :            : * it under the terms of the GNU Lesser General Public License as published by
       6                 :            : * the Free Software Foundation; either version 2 of the License, or
       7                 :            : * (at your option) any later version.
       8                 :            : *
       9                 :            : * This program is distributed in the hope that it will be useful,
      10                 :            : * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11                 :            : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12                 :            : * GNU Lesser General Public License for more details.
      13                 :            : *
      14                 :            : * You should have received a copy of the GNU Lesser General Public License
      15                 :            : * along with this program.  If not, see <http://www.gnu.org/licenses/>
      16                 :            : */
      17                 :            : /*
      18                 :            :  *
      19                 :            :  * NMEA library
      20                 :            :  * URL: http://nmea.sourceforge.net
      21                 :            :  * Author: Tim (xtimor@gmail.com)
      22                 :            :  * Licence: http://www.gnu.org/licenses/lgpl.html
      23                 :            :  * $Id: tok.c 17 2008-03-11 11:56:11Z xtimor $
      24                 :            :  *
      25                 :            :  */
      26                 :            : 
      27                 :            : //! \file tok.h
      28                 :            : 
      29                 :            : #if defined(__clang__)
      30                 :            : #define FALLTHROUGH //[[clang::fallthrough]]
      31                 :            : #elif defined(__GNUC__) && __GNUC__ >= 7
      32                 :            : #define FALLTHROUGH __attribute__((fallthrough));
      33                 :            : #else
      34                 :            : #define FALLTHROUGH
      35                 :            : #endif
      36                 :            : 
      37                 :            : #include "tok.h"
      38                 :            : 
      39                 :            : #include <stdarg.h>
      40                 :            : #include <stdlib.h>
      41                 :            : #include <stdio.h>
      42                 :            : #include <ctype.h>
      43                 :            : #include <string.h>
      44                 :            : #include <limits.h>
      45                 :            : #include <locale.h>
      46                 :            : #include <math.h>
      47                 :            : 
      48                 :            : #define NMEA_TOKS_COMPARE   (1)
      49                 :            : #define NMEA_TOKS_PERCENT   (2)
      50                 :            : #define NMEA_TOKS_WIDTH     (3)
      51                 :            : #define NMEA_TOKS_TYPE      (4)
      52                 :            : 
      53                 :            : /**
      54                 :            :  * \brief Calculate control sum of binary buffer
      55                 :            :  */
      56                 :          0 : int nmea_calc_crc( const char *buff, int buff_sz )
      57                 :            : {
      58                 :          0 :   int chsum = 0,
      59                 :            :       it;
      60                 :            : 
      61                 :          0 :   for ( it = 0; it < buff_sz; ++it )
      62                 :          0 :     chsum ^= ( int )buff[it];
      63                 :            : 
      64                 :          0 :   return chsum;
      65                 :            : }
      66                 :            : 
      67                 :            : /**
      68                 :            :  * \brief Convert string to number
      69                 :            :  */
      70                 :          0 : int nmea_atoi( const char *str, size_t str_sz, int radix )
      71                 :            : {
      72                 :          0 :   char *tmp_ptr = 0;
      73                 :            :   char buff[NMEA_CONVSTR_BUF];
      74                 :          0 :   int res = 0;
      75                 :            : 
      76                 :          0 :   if ( str_sz < NMEA_CONVSTR_BUF )
      77                 :            :   {
      78                 :          0 :     memcpy( &buff[0], str, str_sz );
      79                 :          0 :     buff[str_sz] = '\0';
      80                 :          0 :     res = strtol( &buff[0], &tmp_ptr, radix );
      81                 :          0 :   }
      82                 :            : 
      83                 :          0 :   return res;
      84                 :            : }
      85                 :            : 
      86                 :            : /**
      87                 :            :  * \brief Convert string to fraction number
      88                 :            :  */
      89                 :          0 : double nmea_atof( const char *str, int str_sz )
      90                 :            : {
      91                 :          0 :   char *tmp_ptr = 0;
      92                 :            :   char buff[NMEA_CONVSTR_BUF];
      93                 :          0 :   double res = 0;
      94                 :            : 
      95                 :          0 :   if ( str_sz < NMEA_CONVSTR_BUF )
      96                 :            :   {
      97                 :          0 :     const char *oldlocale = setlocale( LC_NUMERIC, NULL );
      98                 :            : 
      99                 :          0 :     memcpy( &buff[0], str, str_sz );
     100                 :          0 :     buff[str_sz] = '\0';
     101                 :          0 :     setlocale( LC_NUMERIC, "C" );
     102                 :          0 :     res = strtod( &buff[0], &tmp_ptr );
     103                 :          0 :     setlocale( LC_NUMERIC, oldlocale );
     104                 :          0 :   }
     105                 :            : 
     106                 :          0 :   return res;
     107                 :            : }
     108                 :            : 
     109                 :            : /**
     110                 :            :  * \brief Formatting string (like standard printf) with CRC tail (*CRC)
     111                 :            :  */
     112                 :          0 : int nmea_printf( char *buff, int buff_sz, const char *format, ... )
     113                 :            : {
     114                 :          0 :   int retval, add = 0;
     115                 :            :   va_list arg_ptr;
     116                 :            : 
     117                 :          0 :   if ( buff_sz <= 0 )
     118                 :          0 :     return 0;
     119                 :            : 
     120                 :          0 :   va_start( arg_ptr, format );
     121                 :            : 
     122                 :          0 :   retval = NMEA_POSIX( vsnprintf )( buff, buff_sz, format, arg_ptr );
     123                 :            : 
     124                 :          0 :   if ( retval > 0 )
     125                 :            :   {
     126                 :          0 :     add = NMEA_POSIX( snprintf )(
     127                 :          0 :             buff + retval, buff_sz - retval, "*%02x\r\n",
     128                 :          0 :             nmea_calc_crc( buff + 1, retval - 1 ) );
     129                 :          0 :   }
     130                 :            : 
     131                 :          0 :   retval += add;
     132                 :            : 
     133                 :          0 :   if ( retval < 0 || retval > buff_sz )
     134                 :            :   {
     135                 :          0 :     memset( buff, ' ', buff_sz );
     136                 :          0 :     retval = buff_sz;
     137                 :          0 :   }
     138                 :            : 
     139                 :          0 :   va_end( arg_ptr );
     140                 :            : 
     141                 :          0 :   return retval;
     142                 :          0 : }
     143                 :            : 
     144                 :            : /**
     145                 :            :  * \brief Analyze string (specificate for NMEA sentences)
     146                 :            :  */
     147                 :          0 : int nmea_scanf( const char *buff, int buff_sz, const char *format, ... )
     148                 :            : {
     149                 :          0 :   const char *beg_tok = 0;
     150                 :          0 :   const char *end_buf = buff + buff_sz;
     151                 :            : 
     152                 :            :   va_list arg_ptr;
     153                 :          0 :   int tok_type = NMEA_TOKS_COMPARE;
     154                 :          0 :   int width = 0;
     155                 :          0 :   const char *beg_fmt = 0;
     156                 :          0 :   int snum = 0, unum = 0;
     157                 :            : 
     158                 :          0 :   int tok_count = 0;
     159                 :          0 :   void *parg_target = 0;
     160                 :            : 
     161                 :          0 :   va_start( arg_ptr, format );
     162                 :            : 
     163                 :          0 :   for ( ; *format && buff < end_buf; ++format )
     164                 :            :   {
     165                 :          0 :     switch ( tok_type )
     166                 :            :     {
     167                 :            :       case NMEA_TOKS_COMPARE:
     168                 :          0 :         if ( '%' == *format )
     169                 :          0 :           tok_type = NMEA_TOKS_PERCENT;
     170                 :          0 :         else if ( *buff++ != *format )
     171                 :          0 :           goto fail;
     172                 :          0 :         break;
     173                 :            :       case NMEA_TOKS_PERCENT:
     174                 :          0 :         width = 0;
     175                 :          0 :         beg_fmt = format;
     176                 :          0 :         tok_type = NMEA_TOKS_WIDTH;
     177                 :            : 
     178                 :            :         FALLTHROUGH
     179                 :            : 
     180                 :            :       case NMEA_TOKS_WIDTH:
     181                 :            :       {
     182                 :          0 :         if ( isdigit( *format ) )
     183                 :          0 :           break;
     184                 :            : 
     185                 :          0 :         tok_type = NMEA_TOKS_TYPE;
     186                 :          0 :         if ( format > beg_fmt )
     187                 :          0 :           width = nmea_atoi( beg_fmt, ( int )( format - beg_fmt ), 10 );
     188                 :            : 
     189                 :            :         FALLTHROUGH
     190                 :          0 :       }
     191                 :            : 
     192                 :            :       case NMEA_TOKS_TYPE:
     193                 :          0 :         beg_tok = buff;
     194                 :            : 
     195                 :          0 :         if ( !width && ( 'c' == *format || 'C' == *format ) && *buff != format[1] )
     196                 :          0 :           width = 1;
     197                 :            : 
     198                 :          0 :         if ( width )
     199                 :            :         {
     200                 :          0 :           if ( buff + width <= end_buf )
     201                 :          0 :             buff += width;
     202                 :            :           else
     203                 :          0 :             goto fail;
     204                 :          0 :         }
     205                 :            :         else
     206                 :            :         {
     207                 :          0 :           if ( !format[1] || ( 0 == ( buff = ( char * )memchr( buff, format[1], end_buf - buff ) ) ) )
     208                 :          0 :             buff = end_buf;
     209                 :            :         }
     210                 :            : 
     211                 :          0 :         if ( buff > end_buf )
     212                 :          0 :           goto fail;
     213                 :            : 
     214                 :          0 :         tok_type = NMEA_TOKS_COMPARE;
     215                 :          0 :         tok_count++;
     216                 :            : 
     217                 :          0 :         parg_target = 0;
     218                 :          0 :         width = ( int )( buff - beg_tok );
     219                 :            : 
     220                 :          0 :         switch ( *format )
     221                 :            :         {
     222                 :            :           case 'c':
     223                 :            :           case 'C':
     224                 :          0 :             parg_target = ( void * )va_arg( arg_ptr, char * );
     225                 :          0 :             if ( width && 0 != ( parg_target ) )
     226                 :          0 :               *( ( char * )parg_target ) = *beg_tok;
     227                 :          0 :             break;
     228                 :            :           case 's':
     229                 :            :           case 'S':
     230                 :          0 :             parg_target = ( void * )va_arg( arg_ptr, char * );
     231                 :          0 :             if ( width && 0 != ( parg_target ) )
     232                 :            :             {
     233                 :          0 :               memcpy( parg_target, beg_tok, width );
     234                 :          0 :               ( ( char * )parg_target )[width] = '\0';
     235                 :          0 :             }
     236                 :          0 :             break;
     237                 :            :           case 'f':
     238                 :            :           case 'g':
     239                 :            :           case 'G':
     240                 :            :           case 'e':
     241                 :            :           case 'E':
     242                 :          0 :             parg_target = ( void * )va_arg( arg_ptr, double * );
     243                 :          0 :             if ( width && 0 != ( parg_target ) )
     244                 :          0 :               *( ( double * )parg_target ) = nmea_atof( beg_tok, width );
     245                 :          0 :             else if ( width == 0 && 0 != ( parg_target ) )
     246                 :            :             {
     247                 :          0 :               *( ( double * )parg_target ) = NAN;
     248                 :          0 :             }
     249                 :          0 :             break;
     250                 :            :         };
     251                 :            : 
     252                 :          0 :         if ( parg_target )
     253                 :          0 :           break;
     254                 :          0 :         if ( 0 == ( parg_target = ( void * )va_arg( arg_ptr, int * ) ) )
     255                 :          0 :           break;
     256                 :          0 :         if ( !width )
     257                 :          0 :           break;
     258                 :            : 
     259                 :          0 :         switch ( *format )
     260                 :            :         {
     261                 :            :           case 'd':
     262                 :            :           case 'i':
     263                 :          0 :             snum = nmea_atoi( beg_tok, width, 10 );
     264                 :          0 :             memcpy( parg_target, &snum, sizeof( int ) );
     265                 :          0 :             break;
     266                 :            :           case 'u':
     267                 :          0 :             unum = nmea_atoi( beg_tok, width, 10 );
     268                 :          0 :             memcpy( parg_target, &unum, sizeof( unsigned int ) );
     269                 :          0 :             break;
     270                 :            :           case 'x':
     271                 :            :           case 'X':
     272                 :          0 :             unum = nmea_atoi( beg_tok, width, 16 );
     273                 :          0 :             memcpy( parg_target, &unum, sizeof( unsigned int ) );
     274                 :          0 :             break;
     275                 :            :           case 'o':
     276                 :          0 :             unum = nmea_atoi( beg_tok, width, 8 );
     277                 :          0 :             memcpy( parg_target, &unum, sizeof( unsigned int ) );
     278                 :          0 :             break;
     279                 :            :           default:
     280                 :          0 :             goto fail;
     281                 :            :         };
     282                 :            : 
     283                 :          0 :         break;
     284                 :            :     };
     285                 :          0 :   }
     286                 :            : 
     287                 :            : fail:
     288                 :            : 
     289                 :          0 :   va_end( arg_ptr );
     290                 :            : 
     291                 :          0 :   return tok_count;
     292                 :            : }

Generated by: LCOV version 1.14