Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
android /platform /bionic /refs/heads/main /. /libc /bionic /strtol.cpp
blob: 607145d7b80e1d60a2e6ddb8dfff86124be7ddef [file] [log] [blame]
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]1/*
2 * Copyright (c) 1992 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
Elliott Hughesbf03c012020-02-05 11:38:29 -0800[diff] [blame]30#include<ctype.h>
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]31#include<errno.h>
32#include<inttypes.h>
33#include<limits.h>
34#include<stdlib.h>
Elliott Hughes1f462de2022-08-05 22:51:05 +0000[diff] [blame]35#include<wchar.h>
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]36
Elliott Hughes1f462de2022-08-05 22:51:05 +0000[diff] [blame]37template<typename T, TMin, TMax,typenameCharT>
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]38__attribute__((always_inline)) TStrToI(constCharT* s,CharT** end_ptr,int base){
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]39// Ensure that base is between 2 and 36 inclusive, or the special value of 0.
40if(base<0|| base==1|| base>36){
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]41if(end_ptr!=nullptr)*end_ptr=const_cast<CharT*>(s);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]42 errno= EINVAL;
43return0;
44}
45
46// Skip white space and pick up leading +/- sign if any.
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]47constCharT* p= s;
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]48int c;
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]49while(isspace(c=*p++)){
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]50}
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]51bool neg=false;
52if(c=='-'){
53 neg=true;
54 c=*p++;
55}elseif(c=='+'){
56 c=*p++;
57}
58
59// If base is 0 or 16, allow "0x" prefix for hex.
60if((base==0|| base==16)&& c=='0'&&(*p=='x'||*p=='X')&& isxdigit(p[1])){
61 c= p[1];
62 p+=2;
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]63 base=16;
64}
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]65// If base is 0 or 2, allow "0b" prefix for binary.
66if((base==0|| base==2)&& c=='0'&&(*p=='b'||*p=='B')&& isdigit(p[1])){
67 c= p[1];
68 p+=2;
Elliott Hughes1f462de2022-08-05 22:51:05 +0000[diff] [blame]69 base=2;
70}
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]71// If base is 0, allow "0" prefix for octal, otherwise base is 10.
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]72if(base==0) base=(c=='0')?8:10;
73
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]74constexprbool is_signed=(Min!=0);
75 T acc=0;
Elliott Hughescb239bd2017-12-20 17:37:11 -0800[diff] [blame]76// Non-zero if any digits consumed; negative to indicate overflow/underflow.
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]77int any=0;
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]78for(;; c=*p++){
Elliott Hughesbf03c012020-02-05 11:38:29 -0800[diff] [blame]79if(isdigit(c)){
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]80 c-='0';
Elliott Hughesbf03c012020-02-05 11:38:29 -0800[diff] [blame]81}elseif(isalpha(c)){
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]82 c=10+(_tolower(c)-'a');
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]83}else{
84break;
85}
86if(c>= base)break;
87if(any<0)continue;
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]88if(is_signed){
89// We work in the negative space because the most negative value has a
90// larger magnitude than the most positive value.
91if(__builtin_mul_overflow(acc, base,&acc)|| __builtin_sub_overflow(acc, c,&acc)){
92 any=-1;
93continue;
94}
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]95}else{
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]96if(__builtin_mul_overflow(acc, base,&acc)|| __builtin_add_overflow(acc, c,&acc)){
97 any=-1;
98continue;
99}
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]100}
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]101 any=1;
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]102}
103
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]104if(end_ptr!=nullptr)*end_ptr=const_cast<CharT*>(any? p-1: s);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]105
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]106// Detected overflow/underflow in the loop?
107if(any==-1){
108 errno= ERANGE;
109return(is_signed&& neg)?Min:Max;
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]110}
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]111
112// Will we overflow by trying to negate the most negative value?
113if(any>0&& is_signed&&!neg&& acc==Min){
114 errno= ERANGE;
115returnMax;
116}
117
118if(is_signed)return neg? acc:-acc;
119return neg?-acc: acc;
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]120}
121
122int atoi(constchar* s){
123return strtol(s,nullptr,10);
124}
125
126long atol(constchar* s){
127return strtol(s,nullptr,10);
128}
129
130longlong atoll(constchar* s){
131return strtoll(s,nullptr,10);
132}
133
134intmax_t strtoimax(constchar* s,char** end,int base){
Elliott Hughes1f462de2022-08-05 22:51:05 +0000[diff] [blame]135returnStrToI<intmax_t, INTMAX_MIN, INTMAX_MAX,char>(s, end, base);
136}
137
138intmax_t wcstoimax(constwchar_t* s,wchar_t** end,int base){
139returnStrToI<intmax_t, INTMAX_MIN, INTMAX_MAX,wchar_t>(s, end, base);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]140}
141
142long strtol(constchar* s,char** end,int base){
Elliott Hughes1f462de2022-08-05 22:51:05 +0000[diff] [blame]143returnStrToI<long, LONG_MIN, LONG_MAX,char>(s, end, base);
144}
Elliott Hughes1fc68c72024-08-13 15:48:00 +0000[diff] [blame]145__strong_alias(strtol_l, strtol);
Elliott Hughes1f462de2022-08-05 22:51:05 +0000[diff] [blame]146
147long wcstol(constwchar_t* s,wchar_t** end,int base){
148returnStrToI<long, LONG_MIN, LONG_MAX,wchar_t>(s, end, base);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]149}
Elliott Hughes1fc68c72024-08-13 15:48:00 +0000[diff] [blame]150__strong_alias(wcstol_l, wcstol);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]151
152longlong strtoll(constchar* s,char** end,int base){
Elliott Hughes1f462de2022-08-05 22:51:05 +0000[diff] [blame]153returnStrToI<longlong, LLONG_MIN, LLONG_MAX,char>(s, end, base);
154}
Elliott Hughes1fc68c72024-08-13 15:48:00 +0000[diff] [blame]155__strong_alias(strtoll_l, strtoll);
Elliott Hughes1f462de2022-08-05 22:51:05 +0000[diff] [blame]156
157longlong wcstoll(constwchar_t* s,wchar_t** end,int base){
158returnStrToI<longlong, LLONG_MIN, LLONG_MAX,wchar_t>(s, end, base);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]159}
Elliott Hughes1fc68c72024-08-13 15:48:00 +0000[diff] [blame]160__strong_alias(wcstoll_l, wcstoll);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]161
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]162unsignedlong strtoul(constchar* s,char** end,int base){
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]163returnStrToI<unsignedlong,0, ULONG_MAX,char>(s, end, base);
Elliott Hughes1f462de2022-08-05 22:51:05 +0000[diff] [blame]164}
Elliott Hughes1fc68c72024-08-13 15:48:00 +0000[diff] [blame]165__strong_alias(strtoul_l, strtoul);
Elliott Hughes1f462de2022-08-05 22:51:05 +0000[diff] [blame]166
167unsignedlong wcstoul(constwchar_t* s,wchar_t** end,int base){
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]168returnStrToI<unsignedlong,0, ULONG_MAX,wchar_t>(s, end, base);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]169}
Elliott Hughes1fc68c72024-08-13 15:48:00 +0000[diff] [blame]170__strong_alias(wcstoul_l, wcstoul);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]171
172unsignedlonglong strtoull(constchar* s,char** end,int base){
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]173returnStrToI<unsignedlonglong,0, ULLONG_MAX,char>(s, end, base);
Elliott Hughes1f462de2022-08-05 22:51:05 +0000[diff] [blame]174}
Elliott Hughes1fc68c72024-08-13 15:48:00 +0000[diff] [blame]175__strong_alias(strtoull_l, strtoull);
Elliott Hughes1f462de2022-08-05 22:51:05 +0000[diff] [blame]176
177unsignedlonglong wcstoull(constwchar_t* s,wchar_t** end,int base){
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]178returnStrToI<unsignedlonglong,0, ULLONG_MAX,wchar_t>(s, end, base);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]179}
Elliott Hughes1fc68c72024-08-13 15:48:00 +0000[diff] [blame]180__strong_alias(wcstoull_l, wcstoull);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]181
182uintmax_t strtoumax(constchar* s,char** end,int base){
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]183returnStrToI<uintmax_t,0, UINTMAX_MAX,char>(s, end, base);
Elliott Hughes1f462de2022-08-05 22:51:05 +0000[diff] [blame]184}
185
186uintmax_t wcstoumax(constwchar_t* s,wchar_t** end,int base){
Elliott Hughesca89b332023-12-12 14:05:03 -0800[diff] [blame]187returnStrToI<uintmax_t,0, UINTMAX_MAX,wchar_t>(s, end, base);
Elliott Hughes1921dce2017-12-19 10:27:27 -0800[diff] [blame]188}

[8]ページ先頭

©2009-2025 Movatter.jp