Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_string / size_report / format_multiple.cc
1 // Copyright 2019 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://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, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 // This size report uses pw::string::Format and std::snprintf to build a string
16 // in a buffer with multiple calls. The process aborts if an error occurs and
17 // the total string size is returned.
18 //
19 // This compares the overhead of using pw::string::Format to directly calling
20 // std::snprintf and doing error handling. It demonstrates that the code for
21 // using pw::string::Format is much simpler.
22
23 #include "pw_bloat/bloat_this_binary.h"
24
25 #ifndef USE_FORMAT
26 #error "USE_FORMAT must be defined"
27 #endif  // USE_FORMAT
28
29 #if USE_FORMAT
30
31 #include "pw_string/format.h"
32
33 #define FORMAT_FUNCTION(...) \
34   pw::string::Format(std::span(buffer, buffer_size - string_size), __VA_ARGS__)
35 #define CHECK_RESULT(result) ProcessResult(&string_size, result)
36
37 namespace {
38
39 bool ProcessResult(unsigned* total, pw::StatusWithSize result) {
40   *total += result.size();
41   return result.ok();
42 }
43
44 }  // namespace
45
46 #else  // std::snprintf
47
48 #include <cstdio>
49
50 #define FORMAT_FUNCTION(...) std::snprintf(buffer, buffer_size, __VA_ARGS__)
51 #define CHECK_RESULT(result) \
52   ProcessResult(buffer, &string_size, buffer_size - string_size, result)
53
54 namespace {
55
56 bool ProcessResult(char* buffer, unsigned* total, unsigned size, int result) {
57   if (result < 0) {
58     // Null-terminate since snprintf doesn't report the written count.
59     buffer[size] = '\0';
60     return false;
61   }
62
63   if (static_cast<unsigned>(result) >= size) {
64     if (size > 0u) {
65       *total += size - 1;
66     }
67     return false;
68   }
69
70   *total += result;
71   return true;
72 }
73
74 }  // namespace
75
76 #endif  // USE_FORMAT
77
78 #define FORMAT_CASE(...)                             \
79   if (!CHECK_RESULT(FORMAT_FUNCTION(__VA_ARGS__))) { \
80     return string_size;                              \
81   }
82
83 namespace pw::string {
84
85 char* volatile get_buffer;
86 volatile unsigned get_size;
87
88 unsigned OutputStringsToBuffer() {
89   char* buffer = get_buffer;
90   const char* string = get_buffer;
91
92   unsigned buffer_size = get_size;
93   unsigned string_size = 0;
94
95   FORMAT_CASE("The quick brown");
96   FORMAT_CASE("%s", string);
97   FORMAT_CASE("jumped over the %s d%ug.", string, buffer_size);
98   FORMAT_CASE("One two %s %d %s", "three", 4, "five");
99   FORMAT_CASE("a %c %x d %s %f g", 'b', 0xc, "e", 0.0f);
100
101   FORMAT_CASE("The quick brown");
102   FORMAT_CASE("%s", string);
103   FORMAT_CASE("jumped over the %s d%ug.", string, buffer_size);
104   FORMAT_CASE("One two %s %d %s", "three", 4, "five");
105   FORMAT_CASE("a %c %x d %s %f g", 'b', 0xc, "e", 0.0f);
106
107   return string_size;
108 }
109
110 }  // namespace pw::string
111
112 int main() {
113   pw::bloat::BloatThisBinary();
114   return pw::string::OutputStringsToBuffer();
115 }