MCPcopy Create free account
hub / github.com/ROCm/clr / format

Function format

rocclr/device/devhcprintf.cpp:168–228  ·  view source on GitHub ↗

\brief Process a printf message using the system printf function. * \param begin Start of the uint64_t array containing the message. * \param end One past the last element in the array. * \return An integer that satisfies the POSIX return value for printf. * * The message has the following format: * - uint64_t version, required to be zero. * - Format string padded to an 8 byte boundary.

Source from the content-addressed store, hash-verified

166 * - %n specifier is ignored and the corresponding argument is skipped.
167 */
168static int format(FILE* stream, const uint64_t* begin, const uint64_t* end) {
169 const char convSpecifiers[] = "diouxXfFeEgGaAcspn";
170 auto ptr = begin;
171
172 const std::string fmt(reinterpret_cast<const char*>(ptr));
173 ptr += (fmt.length() + 7 + 1) / 8; // the extra '1' is for the null
174
175 int outCount = 0;
176 size_t point = 0;
177 while (true) {
178 // Each segment of the format string delineated by [mark,
179 // point) is handled seprately.
180 auto mark = point;
181 point = fmt.find('%', point);
182
183 // Two different cases where a literal segment is printed out.
184 // 1. When the point reaches the end of the format string.
185 // 2. When the point is at the start of a format specifier.
186 if (point == std::string::npos) {
187 checkPrintf(stream, &outCount, "%s", &fmt[mark]);
188 return outCount;
189 }
190 checkPrintf(stream, &outCount, "%.*s", (int)(point - mark), &fmt[mark]);
191 if (outCount < 0) {
192 return outCount;
193 }
194
195 mark = point;
196 ++point;
197
198 // Handle the simplest specifier, '%%'.
199 if (fmt[point] == '%') {
200 checkPrintf(stream, &outCount, "%%");
201 if (outCount < 0) {
202 return outCount;
203 }
204 ++point;
205 continue;
206 }
207
208 // Before processing the specifier, check if we have run out
209 // of arguments.
210 if (ptr == end) {
211 return outCount;
212 }
213
214 // Undefined behaviour if we don't see a conversion specifier.
215 point = fmt.find_first_of(convSpecifiers, point);
216 if (point == std::string::npos) {
217 return outCount;
218 }
219 ++point;
220
221 // [mark,point) now contains a complete specifier.
222 const std::string spec(fmt, mark, point - mark);
223 ptr = processSpec(stream, &outCount, spec, ptr, end);
224 if (outCount < 0) {
225 return outCount;

Callers 2

handlePrintfFunction · 0.85
handlePrintfDelayedFunction · 0.85

Calls 2

checkPrintfFunction · 0.85
processSpecFunction · 0.85

Tested by

no test coverage detected