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