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::StringBuilder (via pw::MakeString) and
16 // std::snprintf to build a string.
17 //
18 // This compares the binary size cost of StringBuilder when it is used instead
19 // of std::snprintf and when it is used alongside std::snprintf. StringBuilder
20 // does not use std::snprintf (unless StringBuilder::Format is called), so using
21 // StringBuilder may allow binaries to avoid std::snprintf altogether.
22
23 #include <cstdio>
24
25 #include "pw_bloat/bloat_this_binary.h"
26 #include "pw_string/string_builder.h"
27
28 #if !defined(USE_STRING_BUILDER) || !defined(PROVIDE_BASE_SNPRINTF)
29 #error "USE_STRING_BUILDER must be defined"
30 #endif // !defined(USE_STRING_BUILDER) || !defined(PROVIDE_BASE_SNPRINTF)
31
32 #if USE_STRING_BUILDER
33
34 #include "pw_string/string_builder.h"
35
36 #else
37
BytesWritten(char * buffer,unsigned size,int result)38 unsigned BytesWritten(char* buffer, unsigned size, int result) {
39 if (result < 0) {
40 // Null-terminate since snprintf doesn't report the written count.
41 buffer[size] = '\0';
42 return 0;
43 }
44
45 if (static_cast<unsigned>(result) >= size) {
46 return size > 0u ? size - 1 : 0;
47 }
48
49 return result;
50 }
51
52 #endif
53
54 char string[64] = "hello";
55
56 volatile bool get_boolean;
57 volatile int get_integer;
58 const char* volatile get_string;
59
main()60 int main() {
61 int integer = get_integer;
62 bool boolean = get_boolean;
63
64 #if PROVIDE_BASE_SNPRINTF
65 std::snprintf(string, sizeof(string), "%d", 1234);
66 #endif // PROVIDE_BASE_SNPRINTF
67
68 #if USE_STRING_BUILDER
69 return pw::MakeString<64>("Hello, ",
70 string,
71 ". The answer to 3 == ",
72 integer,
73 " is ",
74 boolean)
75 .size();
76
77 #else
78 char buffer[64];
79
80 int result = std::snprintf(buffer,
81 sizeof(buffer),
82 "Hello, %s. The answer to 3 == %d is %s.",
83 string,
84 integer,
85 boolean ? "true" : "false");
86
87 return BytesWritten(buffer, sizeof(buffer), result);
88
89 #endif // USE_STRING_BUILDER
90 }
91