LCOV - code coverage report
Current view: top level - u8stream/source/utf8stringbuf - utf8string.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.63.2_covts Lines: 100.0 % 49 49
Test Date: 2025-05-01 10:10:14 Functions: 100.0 % 2 2

            Line data    Source code
       1              : /* File: utf8string.c; Copyright and License: see below */
       2              : 
       3              : #include "utf8stringbuf/utf8string.h"
       4              : #include "utf8stringbuf/utf8codepoint.h"
       5              : #include "utf8stringbuf/utf8stringbuf.h"
       6              : #include "u8_test_cond.h"
       7              : #include "u8/u8_fault_inject.h"
       8              : #include <string.h>
       9              : #include <stdio.h>
      10              : #include <stdint.h>
      11              : #include <stdlib.h>
      12              : #include <errno.h>
      13              : #include <limits.h>
      14              : #include <locale.h>
      15              : #include <math.h>
      16              : 
      17              : #ifdef __cplusplus
      18              : extern "C" {
      19              : #endif
      20              : 
      21           40 : utf8error_t utf8string_parse_int( utf8string_t *this_, unsigned int *out_byte_length, int64_t *out_number )
      22              : {
      23           40 :     utf8error_t result = UTF8ERROR_SUCCESS;
      24           40 :     if (( this_ != NULL )&&( out_number != NULL )) {
      25           39 :         char *endptr = NULL;
      26           39 :         errno = 0;
      27           39 :         long long parseResult = strtoll( this_, &endptr, 10 /* base */);
      28           39 :         if ((parseResult==0)||(parseResult==LLONG_MIN)||(parseResult==LLONG_MAX))
      29              :         {
      30           18 :             if (( errno == ERANGE )||( errno == EINVAL )) {
      31            5 :                 result = UTF8ERROR_OUT_OF_RANGE;
      32              :             }
      33              :         }
      34           39 :         assert( endptr != NULL );  /* this should not happen, but do not take this for granted */
      35           39 :         U8_FAULT_INJECT_COND_SET( U8_TEST_COND_STRTOLL, endptr, NULL );
      36              :         unsigned int length;
      37           39 :         if ( endptr == NULL ) {
      38            1 :             length = utf8string_get_length( this_ );
      39              :         }
      40              :         else {
      41           38 :             length = (int)(endptr-this_);
      42              :         }
      43           39 :         if ( out_byte_length != NULL ) {
      44           38 :             *out_byte_length = length;
      45              :         }
      46           39 :         if ( length == 0 )
      47              :         {
      48            7 :             result = UTF8ERROR_NOT_FOUND;
      49              :         }
      50           39 :         *out_number = parseResult;
      51              :     }
      52              :     else {
      53            1 :         result = UTF8ERROR_NULL_PARAM;
      54              :     }
      55           40 :     return result;
      56              : }
      57              : 
      58          205 : utf8error_t utf8string_parse_float( utf8string_t *this_, unsigned int *out_byte_length, double *out_number )
      59              : {
      60          205 :     utf8error_t result = UTF8ERROR_SUCCESS;
      61          205 :     if (( this_ != NULL )&&( out_number != NULL )) {
      62          204 :         char *endptr = NULL;
      63          204 :         errno = 0;
      64          204 :         const char *const default_locale_temp = setlocale( LC_NUMERIC, NULL );  /* get the current locale */
      65              :         char default_locale_buf[20];  /* expecting max length = 19: sr_YU.utf8@cyrillic */
      66          204 :         utf8stringbuf_t default_locale = UTF8STRINGBUF( default_locale_buf );
      67          204 :         utf8stringbuf_copy_str( &default_locale, default_locale_temp );
      68          204 :         const char *const c_locale = setlocale( LC_NUMERIC, "C" );  /* set separator to point (by C locale) */
      69          204 :         assert ( c_locale != NULL );
      70              :         (void) c_locale;
      71          204 :         double parseResult = strtod( this_, &endptr );
      72          204 :         const char *const restored_locale = setlocale( LC_NUMERIC, utf8stringbuf_get_string( &default_locale ) );  /* set separator back to previous character */
      73          204 :         assert ( restored_locale != NULL );
      74              :         (void) restored_locale;
      75          204 :         if ((parseResult==INFINITY)||(parseResult==-INFINITY)||(parseResult==0.0)||(parseResult==-0.0))
      76              :         {
      77           41 :             if (( errno == ERANGE )||( errno == EINVAL )) {
      78            4 :                 result = UTF8ERROR_OUT_OF_RANGE;
      79              :             }
      80              :         }
      81          204 :         assert( endptr != NULL );  /* this should not happen, but do not take this for granted */
      82          204 :         U8_FAULT_INJECT_COND_SET( U8_TEST_COND_STRTOD, endptr, NULL );
      83              :         unsigned int length;
      84          204 :         if ( endptr == NULL ) {
      85            1 :             length = utf8string_get_length( this_ );
      86              :         }
      87              :         else {
      88          203 :             length = (int)(endptr-this_);
      89              :         }
      90          204 :         if ( out_byte_length != NULL ) {
      91          203 :             *out_byte_length = length;
      92              :         }
      93          204 :         if ( length == 0 )
      94              :         {
      95            6 :             result = UTF8ERROR_NOT_FOUND;
      96              :         }
      97          204 :         *out_number = parseResult;
      98              :     }
      99              :     else {
     100            1 :         result = UTF8ERROR_NULL_PARAM;
     101              :     }
     102          205 :     return result;
     103              : }
     104              : 
     105              : #ifdef __cplusplus
     106              : }
     107              : #endif
     108              : 
     109              : 
     110              : /*
     111              :  * Copyright 2023-2025 Andreas Warnke
     112              :  *
     113              :  * Licensed under the Apache License, Version 2.0 (the "License");
     114              :  * you may not use this file except in compliance with the License.
     115              :  * You may obtain a copy of the License at
     116              :  *
     117              :  *    http://www.apache.org/licenses/LICENSE-2.0
     118              :  *
     119              :  * Unless required by applicable law or agreed to in writing, software
     120              :  * distributed under the License is distributed on an "AS IS" BASIS,
     121              :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     122              :  * See the License for the specific language governing permissions and
     123              :  * limitations under the License.
     124              :  */
        

Generated by: LCOV version 2.0-1