LCOV - code coverage report
Current view: top level - u8stream/source/utf8stringbuf - utf8string.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.61.0_covts Lines: 49 49 100.0 %
Date: 2024-10-26 21:44:38 Functions: 2 2 100.0 %

          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-2024 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 1.16