1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 #include <string>
19 
20 static const std::string kFormatChars = std::string("duoxXfFeEgGaAcsp");
21 static constexpr int32_t kMaxFormatFlagValue = INT16_MAX;
22 enum FormatChar : uint8_t {
23     SIGNED_DECIMAL = 0,
24     UNSIGNED_DECIMAL = 1,
25     UNSIGNED_OCTAL = 2,
26     UNSIGNED_HEX_LOWER = 3,
27     UNSIGNED_HEX_UPPER = 4,
28     // Uppercase/lowercase floating point impacts 'inf', 'infinity', and 'nan'
29     FLOAT_LOWER = 5,
30     FLOAT_UPPER = 6,
31     // Upper/lower impacts the "e" in exponents.
32     EXPONENT_LOWER = 7,
33     EXPONENT_UPPER = 8,
34     // %g will use %e or %f, whichever is shortest
35     SHORT_EXP_LOWER = 9,
36     // %G will use %E or %F, whichever is shortest
37     SHORT_EXP_UPPER = 10,
38     HEX_FLOAT_LOWER = 11,
39     HEX_FLOAT_UPPER = 12,
40     CHAR = 13,
41     STRING = 14,
42     POINTER = 15,
43     // Used by libfuzzer
44     kMaxValue = POINTER
45 };
46 
canApplyFlag(FormatChar formatChar,char modifier)47 bool canApplyFlag(FormatChar formatChar, char modifier) {
48     if (modifier == '#') {
49         return formatChar == UNSIGNED_OCTAL || formatChar == UNSIGNED_HEX_LOWER ||
50                formatChar == UNSIGNED_HEX_UPPER || formatChar == FLOAT_LOWER ||
51                formatChar == FLOAT_UPPER || formatChar == SHORT_EXP_LOWER ||
52                formatChar == SHORT_EXP_UPPER;
53     } else if (modifier == '.') {
54         return formatChar == SIGNED_DECIMAL || formatChar == UNSIGNED_DECIMAL ||
55                formatChar == UNSIGNED_OCTAL || formatChar == UNSIGNED_HEX_LOWER ||
56                formatChar == UNSIGNED_HEX_UPPER || formatChar == FLOAT_LOWER ||
57                formatChar == FLOAT_UPPER || formatChar == SHORT_EXP_LOWER ||
58                formatChar == SHORT_EXP_UPPER || formatChar == STRING;
59     }
60     return true;
61 }
62