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 : */