Coverage Report

Created: 2024-07-09 06:09

/proc/self/cwd/pw_string/format.cc
Line
Count
Source (jump to first uncovered line)
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
15
#include "pw_string/format.h"
16
17
#include <cstdio>
18
19
namespace pw::string {
20
21
0
StatusWithSize Format(span<char> buffer, const char* format, ...) {
22
0
  va_list args;
23
0
  va_start(args, format);
24
0
  const StatusWithSize result = FormatVaList(buffer, format, args);
25
0
  va_end(args);
26
27
0
  return result;
28
0
}
29
30
StatusWithSize FormatVaList(span<char> buffer,
31
                            const char* format,
32
0
                            va_list args) {
33
0
  if (buffer.empty()) {
34
0
    return StatusWithSize::ResourceExhausted();
35
0
  }
36
37
0
  const int result = std::vsnprintf(buffer.data(), buffer.size(), format, args);
38
39
  // If an error occurred, the number of characters written is unknown.
40
  // Discard any output by terminating the buffer.
41
0
  if (result < 0) {
42
0
    buffer[0] = '\0';
43
0
    return StatusWithSize::InvalidArgument();
44
0
  }
45
46
  // If result >= buffer.size(), the output was truncated and null-terminated.
47
0
  if (static_cast<unsigned>(result) >= buffer.size()) {
48
0
    return StatusWithSize::ResourceExhausted(buffer.size() - 1);
49
0
  }
50
51
0
  return StatusWithSize(result);
52
0
}
53
54
0
Status Format(InlineString<>& string, const char* format, ...) {
55
0
  va_list args;
56
0
  va_start(args, format);
57
0
  const Status status = FormatVaList(string, format, args);
58
0
  va_end(args);
59
60
0
  return status;
61
0
}
62
63
0
Status FormatVaList(InlineString<>& string, const char* format, va_list args) {
64
0
  Status status;
65
0
  string.resize_and_overwrite([&](char* buffer, size_t capacity) {
66
    // The vsnprintf buffer size includes a byte for the null terminator.
67
0
    StatusWithSize result =
68
0
        FormatVaList(span(buffer + string.size(), capacity + 1 - string.size()),
69
0
                     format,
70
0
                     args);
71
0
    status = result.status();
72
0
    return string.size() + result.size();
73
0
  });
74
0
  return status;
75
0
}
76
77
0
Status FormatOverwrite(InlineString<>& string, const char* format, ...) {
78
0
  va_list args;
79
0
  va_start(args, format);
80
0
  const Status status = FormatOverwriteVaList(string, format, args);
81
0
  va_end(args);
82
83
0
  return status;
84
0
}
85
86
}  // namespace pw::string