1 // Copyright 2023 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 #pragma once
15
16 /// @file pw_string/format.h
17 ///
18 /// The `pw::string::Format` functions are safer alternatives to `std::snprintf`
19 /// and `std::vsnprintf`. The `snprintf` return value is awkward to interpret,
20 /// and misinterpreting it can lead to serious bugs.
21 ///
22 /// These functions return a `pw::StatusWithSize`. The `pw::Status` is set to
23 /// reflect any errors and the return value is always the number of characters
24 /// written before the null terminator.
25
26 #include <cstdarg>
27
28 #include "pw_preprocessor/compiler.h"
29 #include "pw_span/span.h"
30 #include "pw_status/status_with_size.h"
31 #include "pw_string/string.h"
32
33 namespace pw::string {
34
35 /// Writes a printf-style formatted string to the provided buffer, similarly to
36 /// `std::snprintf()`.
37 ///
38 /// The `std::snprintf()` return value is awkward to interpret, and
39 /// misinterpreting it can lead to serious bugs.
40 ///
41 /// @returns @rst
42 ///
43 /// .. pw-status-codes::
44 ///
45 /// OK: Returns the number of characters written, excluding the null
46 /// terminator. The buffer is always null-terminated unless it is empty.
47 ///
48 /// RESOURCE_EXHAUSTED: The buffer was too small to fit the output.
49 ///
50 /// INVALID_ARGUMENT: There was a formatting error.
51 ///
52 /// @endrst
53 PW_PRINTF_FORMAT(2, 3)
54 StatusWithSize Format(span<char> buffer, const char* format, ...);
55
56 /// Writes a printf-style formatted string with va_list-packed arguments to the
57 /// provided buffer, similarly to `std::vsnprintf()`.
58 ///
59 /// @returns See `pw::string::Format()`.
60 PW_PRINTF_FORMAT(2, 0)
61 StatusWithSize FormatVaList(span<char> buffer,
62 const char* format,
63 va_list args);
64
65 /// Appends a printf-style formatted string to the provided `pw::InlineString`,
66 /// similarly to `std::snprintf()`.
67 ///
68 /// @returns See `pw::string::Format()`.
69 PW_PRINTF_FORMAT(2, 3)
70 Status Format(InlineString<>& string, const char* format, ...);
71
72 /// Appends a printf-style formatted string with va_list-packed arguments to the
73 /// provided `InlineString`, similarly to `std::vsnprintf()`.
74 ///
75 /// @returns See `pw::string::Format()`.
76 PW_PRINTF_FORMAT(2, 0)
77 Status FormatVaList(InlineString<>& string, const char* format, va_list args);
78
79 /// Writes a printf-style format string to the provided `InlineString`,
80 /// overwriting any contents.
81 ///
82 /// @returns See `pw::string::Format()`.
83 PW_PRINTF_FORMAT(2, 3)
84 Status FormatOverwrite(InlineString<>& string, const char* format, ...);
85
86 /// Writes a printf-style formatted string with `va_list`-packed arguments to
87 /// the provided `InlineString`, overwriting any contents.
88 ///
89 /// @returns See `pw::string::Format()`.
90 PW_PRINTF_FORMAT(2, 0)
FormatOverwriteVaList(InlineString<> & string,const char * format,va_list args)91 inline Status FormatOverwriteVaList(InlineString<>& string,
92 const char* format,
93 va_list args) {
94 string.clear();
95 return FormatVaList(string, format, args);
96 }
97
98 } // namespace pw::string
99