1 // Copyright 2019 The Pigweed Authors
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
7 // https://www.apache.org/licenses/LICENSE-2.0
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
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.
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.
23 #include "pw_bloat/bloat_this_binary.h"
26 #error "USE_FORMAT must be defined"
31 #include "pw_string/format.h"
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)
39 bool ProcessResult(unsigned* total, pw::StatusWithSize result) {
40 *total += result.size();
46 #else // std::snprintf
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)
56 bool ProcessResult(char* buffer, unsigned* total, unsigned size, int result) {
58 // Null-terminate since snprintf doesn't report the written count.
63 if (static_cast<unsigned>(result) >= size) {
78 #define FORMAT_CASE(...) \
79 if (!CHECK_RESULT(FORMAT_FUNCTION(__VA_ARGS__))) { \
83 namespace pw::string {
85 char* volatile get_buffer;
86 volatile unsigned get_size;
88 unsigned OutputStringsToBuffer() {
89 char* buffer = get_buffer;
90 const char* string = get_buffer;
92 unsigned buffer_size = get_size;
93 unsigned string_size = 0;
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);
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);
110 } // namespace pw::string
113 pw::bloat::BloatThisBinary();
114 return pw::string::OutputStringsToBuffer();