• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef ASSEMBLER_UTILS_NUMBER_UTILS_H
17 #define ASSEMBLER_UTILS_NUMBER_UTILS_H
18 
19 namespace panda::pandasm {
20 
21 constexpr size_t HEX_BASE = 16;
22 
23 constexpr size_t DEC_BASE = 10;
24 
25 constexpr size_t OCT_BASE = 8;
26 
27 constexpr size_t BIN_BASE = 2;
28 
29 constexpr size_t MAX_DWORD = 65536;
30 
ValidateInteger(std::string_view p)31 inline bool ValidateInteger(std::string_view p)
32 {
33     constexpr size_t GENERAL_SHIFT = 2;
34 
35     std::string_view token = p;
36 
37     if (token.back() == '-' || token.back() == '+' || token.back() == 'x' || token == ".") {
38         return false;
39     }
40 
41     if (token[0] == '-' || token[0] == '+') {
42         token.remove_prefix(1);
43     }
44 
45     if (token[0] == '0' && token.size() > 1 && token.find('.') == std::string::npos) {
46         if (token[1] == 'x') {
47             token.remove_prefix(GENERAL_SHIFT);
48 
49             for (auto i : token) {
50                 if (!((i >= '0' && i <= '9') || (i >= 'A' && i <= 'F') || (i >= 'a' && i <= 'f'))) {
51                     return false;
52                 }
53             }
54 
55             return true;
56         }
57 
58         if (token[1] == 'b') {
59             token.remove_prefix(GENERAL_SHIFT);
60             if (token.empty()) {
61                 return false;
62             }
63             for (auto i : token) {
64                 if (!(i == '0' || i == '1')) {
65                     return false;
66                 }
67             }
68 
69             return true;
70         }
71 
72         if (token[1] >= '0' && token[1] <= '9' && token.find('e') == std::string::npos) {
73             token.remove_prefix(1);
74 
75             for (auto i : token) {
76                 if (!(i >= '0' && i <= '7')) {
77                     return false;
78                 }
79             }
80 
81             return true;
82         }
83     }
84 
85     for (auto i : token) {
86         if (!(i >= '0' && i <= '9')) {
87             return false;
88         }
89     }
90 
91     return true;
92 }
93 
IntegerNumber(std::string_view p)94 inline int64_t IntegerNumber(std::string_view p)
95 {
96     constexpr size_t GENERAL_SHIFT = 2;
97 
98     // expects a valid number
99     if (p.size() == 1) {
100         return p[0] - '0';
101     }
102 
103     size_t minus_shift = 0;
104     if (p[0] == '-') {
105         minus_shift++;
106     }
107 
108     if (p[minus_shift + 1] == 'b') {
109         p.remove_prefix(GENERAL_SHIFT + minus_shift);
110         return std::strtoull(p.data(), nullptr, BIN_BASE) * (minus_shift == 0 ? 1 : -1);
111     }
112 
113     if (p[minus_shift + 1] == 'x') {
114         return std::strtoull(p.data(), nullptr, HEX_BASE);
115     }
116 
117     if (p[minus_shift] == '0') {
118         return std::strtoull(p.data(), nullptr, OCT_BASE);
119     }
120 
121     return std::strtoull(p.data(), nullptr, DEC_BASE);
122 }
123 
ValidateFloat(std::string_view p)124 inline bool ValidateFloat(std::string_view p)
125 {
126     std::string_view token = p;
127 
128     if (ValidateInteger(token)) {
129         return true;
130     }
131 
132     if (token[0] == '-' || token[0] == '+') {
133         token.remove_prefix(1);
134     }
135 
136     bool dot = false;
137     bool exp = false;
138     bool nowexp = false;
139 
140     for (auto i : token) {
141         if (nowexp && (i == '-' || i == '+')) {
142             nowexp = false;
143             continue;
144         }
145 
146         if (nowexp) {
147             nowexp = false;
148         }
149 
150         if (i == '.' && !exp && !dot) {
151             dot = true;
152         } else if (!exp && i == 'e') {
153             nowexp = true;
154             exp = true;
155         } else if (!(i >= '0' && i <= '9')) {
156             return false;
157         }
158     }
159 
160     return !nowexp;
161 }
162 
FloatNumber(std::string_view p,bool is_64bit)163 inline double FloatNumber(std::string_view p, bool is_64bit)
164 {
165     constexpr size_t GENERAL_SHIFT = 2;
166     // expects a valid number
167     if (p.size() > GENERAL_SHIFT && p.substr(0, GENERAL_SHIFT) == "0x") {  // hex literal
168         char *end = nullptr;
169         if (is_64bit) {
170             return bit_cast<double>(strtoull(p.data(), &end, 0));
171         } else {
172             return bit_cast<float>(static_cast<uint32_t>(strtoull(p.data(), &end, 0)));
173         }
174     }
175     return std::strtold(std::string(p.data(), p.length()).c_str(), nullptr);
176 }
177 
ToNumber(std::string_view p)178 inline size_t ToNumber(std::string_view p)
179 {
180     size_t sum = 0;
181 
182     for (char i : p) {
183         if (isdigit(i) != 0) {
184             sum = sum * DEC_BASE + static_cast<size_t>(i - '0');
185         } else {
186             return MAX_DWORD;
187         }
188     }
189 
190     return sum;
191 }
192 
193 }  // namespace panda::pandasm
194 
195 #endif  // ASSEMBLER_UTILS_NUMBER_UTILS_H
196