| David Greene | 20f6ac0 | 2009-07-13 16:49:27 +0000 | [diff] [blame] | 1 | //===-- llvm/Support/FormattedStream.cpp - Formatted streams ----*- C++ -*-===// | 
| David Greene | c97b778b | 2009-07-10 21:14:44 +0000 | [diff] [blame] | 2 | // | 
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | 4 | // See https://llvm.org/LICENSE.txt for license information. | 
|  | 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
| David Greene | c97b778b | 2009-07-10 21:14:44 +0000 | [diff] [blame] | 6 | // | 
|  | 7 | //===----------------------------------------------------------------------===// | 
|  | 8 | // | 
| Chris Lattner | ca99c34 | 2009-07-14 23:14:10 +0000 | [diff] [blame] | 9 | // This file contains the implementation of formatted_raw_ostream. | 
| David Greene | c97b778b | 2009-07-10 21:14:44 +0000 | [diff] [blame] | 10 | // | 
|  | 11 | //===----------------------------------------------------------------------===// | 
|  | 12 |  | 
|  | 13 | #include "llvm/Support/FormattedStream.h" | 
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 14 | #include "llvm/Support/Debug.h" | 
| Benjamin Kramer | 799003b | 2015-03-23 19:32:43 +0000 | [diff] [blame] | 15 | #include "llvm/Support/raw_ostream.h" | 
| Nick Lewycky | 0de20af | 2010-12-19 20:43:38 +0000 | [diff] [blame] | 16 | #include <algorithm> | 
| David Greene | 8e621f0 | 2009-07-23 23:21:10 +0000 | [diff] [blame] | 17 |  | 
| David Greene | 20f6ac0 | 2009-07-13 16:49:27 +0000 | [diff] [blame] | 18 | using namespace llvm; | 
| David Greene | c97b778b | 2009-07-10 21:14:44 +0000 | [diff] [blame] | 19 |  | 
| Daniel Malea | f83beab | 2013-05-08 20:29:10 +0000 | [diff] [blame] | 20 | /// UpdatePosition - Examine the given char sequence and figure out which | 
|  | 21 | /// column we end up in after output, and how many line breaks are contained. | 
| David Greene | 20f6ac0 | 2009-07-13 16:49:27 +0000 | [diff] [blame] | 22 | /// | 
| Daniel Malea | f83beab | 2013-05-08 20:29:10 +0000 | [diff] [blame] | 23 | static void UpdatePosition(std::pair<unsigned, unsigned> &Position, const char *Ptr, size_t Size) { | 
|  | 24 | unsigned &Column = Position.first; | 
|  | 25 | unsigned &Line = Position.second; | 
| David Greene | c97b778b | 2009-07-10 21:14:44 +0000 | [diff] [blame] | 26 |  | 
| Daniel Malea | f83beab | 2013-05-08 20:29:10 +0000 | [diff] [blame] | 27 | // Keep track of the current column and line by scanning the string for | 
|  | 28 | // special characters | 
| Dan Gohman | 186b85d | 2009-08-15 02:02:59 +0000 | [diff] [blame] | 29 | for (const char *End = Ptr + Size; Ptr != End; ++Ptr) { | 
|  | 30 | ++Column; | 
| Daniel Malea | f83beab | 2013-05-08 20:29:10 +0000 | [diff] [blame] | 31 | switch (*Ptr) { | 
|  | 32 | case '\n': | 
|  | 33 | Line += 1; | 
| Galina Kistanova | 78706a3 | 2017-05-19 21:08:28 +0000 | [diff] [blame] | 34 | LLVM_FALLTHROUGH; | 
| Daniel Malea | f83beab | 2013-05-08 20:29:10 +0000 | [diff] [blame] | 35 | case '\r': | 
| Dan Gohman | 186b85d | 2009-08-15 02:02:59 +0000 | [diff] [blame] | 36 | Column = 0; | 
| Daniel Malea | f83beab | 2013-05-08 20:29:10 +0000 | [diff] [blame] | 37 | break; | 
|  | 38 | case '\t': | 
| Dan Gohman | 186b85d | 2009-08-15 02:02:59 +0000 | [diff] [blame] | 39 | // Assumes tab stop = 8 characters. | 
|  | 40 | Column += (8 - (Column & 0x7)) & 0x7; | 
| Daniel Malea | f83beab | 2013-05-08 20:29:10 +0000 | [diff] [blame] | 41 | break; | 
|  | 42 | } | 
| David Greene | ea2f1ce | 2009-07-29 16:08:27 +0000 | [diff] [blame] | 43 | } | 
| Dan Gohman | 186b85d | 2009-08-15 02:02:59 +0000 | [diff] [blame] | 44 | } | 
|  | 45 |  | 
| Daniel Malea | f83beab | 2013-05-08 20:29:10 +0000 | [diff] [blame] | 46 | /// ComputePosition - Examine the current output and update line and column | 
|  | 47 | /// counts. | 
|  | 48 | void formatted_raw_ostream::ComputePosition(const char *Ptr, size_t Size) { | 
| Daniel Dunbar | 17a6fd2 | 2009-08-18 23:36:04 +0000 | [diff] [blame] | 49 | // If our previous scan pointer is inside the buffer, assume we already | 
|  | 50 | // scanned those bytes. This depends on raw_ostream to not change our buffer | 
|  | 51 | // in unexpected ways. | 
| Daniel Malea | f83beab | 2013-05-08 20:29:10 +0000 | [diff] [blame] | 52 | if (Ptr <= Scanned && Scanned <= Ptr + Size) | 
| Daniel Dunbar | 17a6fd2 | 2009-08-18 23:36:04 +0000 | [diff] [blame] | 53 | // Scan all characters added since our last scan to determine the new | 
|  | 54 | // column. | 
| Daniel Malea | f83beab | 2013-05-08 20:29:10 +0000 | [diff] [blame] | 55 | UpdatePosition(Position, Scanned, Size - (Scanned - Ptr)); | 
|  | 56 | else | 
|  | 57 | UpdatePosition(Position, Ptr, Size); | 
| Daniel Dunbar | 17a6fd2 | 2009-08-18 23:36:04 +0000 | [diff] [blame] | 58 |  | 
|  | 59 | // Update the scanning pointer. | 
|  | 60 | Scanned = Ptr + Size; | 
| David Greene | c97b778b | 2009-07-10 21:14:44 +0000 | [diff] [blame] | 61 | } | 
| David Greene | 20f6ac0 | 2009-07-13 16:49:27 +0000 | [diff] [blame] | 62 |  | 
|  | 63 | /// PadToColumn - Align the output to some column number. | 
|  | 64 | /// | 
|  | 65 | /// \param NewCol - The column to move to. | 
| David Greene | 20f6ac0 | 2009-07-13 16:49:27 +0000 | [diff] [blame] | 66 | /// | 
| Fangrui Song | f78650a | 2018-07-30 19:41:25 +0000 | [diff] [blame] | 67 | formatted_raw_ostream &formatted_raw_ostream::PadToColumn(unsigned NewCol) { | 
| David Greene | ea2f1ce | 2009-07-29 16:08:27 +0000 | [diff] [blame] | 68 | // Figure out what's in the buffer and add it to the column count. | 
| Daniel Malea | f83beab | 2013-05-08 20:29:10 +0000 | [diff] [blame] | 69 | ComputePosition(getBufferStart(), GetNumBytesInBuffer()); | 
| David Greene | 20f6ac0 | 2009-07-13 16:49:27 +0000 | [diff] [blame] | 70 |  | 
|  | 71 | // Output spaces until we reach the desired column. | 
| Daniel Malea | f83beab | 2013-05-08 20:29:10 +0000 | [diff] [blame] | 72 | indent(std::max(int(NewCol - getColumn()), 1)); | 
| Chris Lattner | f733d75 | 2010-02-15 02:17:50 +0000 | [diff] [blame] | 73 | return *this; | 
| David Greene | 20f6ac0 | 2009-07-13 16:49:27 +0000 | [diff] [blame] | 74 | } | 
|  | 75 |  | 
| Dan Gohman | 250635e | 2009-08-15 02:01:04 +0000 | [diff] [blame] | 76 | void formatted_raw_ostream::write_impl(const char *Ptr, size_t Size) { | 
| Dan Gohman | 186b85d | 2009-08-15 02:02:59 +0000 | [diff] [blame] | 77 | // Figure out what's in the buffer and add it to the column count. | 
| Daniel Malea | f83beab | 2013-05-08 20:29:10 +0000 | [diff] [blame] | 78 | ComputePosition(Ptr, Size); | 
| Dan Gohman | 186b85d | 2009-08-15 02:02:59 +0000 | [diff] [blame] | 79 |  | 
|  | 80 | // Write the data to the underlying stream (which is unbuffered, so | 
|  | 81 | // the data will be immediately written out). | 
| Dan Gohman | 250635e | 2009-08-15 02:01:04 +0000 | [diff] [blame] | 82 | TheStream->write(Ptr, Size); | 
| Dan Gohman | 186b85d | 2009-08-15 02:02:59 +0000 | [diff] [blame] | 83 |  | 
| Daniel Dunbar | 17a6fd2 | 2009-08-18 23:36:04 +0000 | [diff] [blame] | 84 | // Reset the scanning pointer. | 
| Craig Topper | c10719f | 2014-04-07 04:17:22 +0000 | [diff] [blame] | 85 | Scanned = nullptr; | 
| Dan Gohman | 250635e | 2009-08-15 02:01:04 +0000 | [diff] [blame] | 86 | } | 
|  | 87 |  | 
| David Greene | a31f96c | 2009-07-14 20:18:05 +0000 | [diff] [blame] | 88 | /// fouts() - This returns a reference to a formatted_raw_ostream for | 
|  | 89 | /// standard output.  Use it like: fouts() << "foo" << "bar"; | 
|  | 90 | formatted_raw_ostream &llvm::fouts() { | 
|  | 91 | static formatted_raw_ostream S(outs()); | 
|  | 92 | return S; | 
|  | 93 | } | 
|  | 94 |  | 
|  | 95 | /// ferrs() - This returns a reference to a formatted_raw_ostream for | 
|  | 96 | /// standard error.  Use it like: ferrs() << "foo" << "bar"; | 
|  | 97 | formatted_raw_ostream &llvm::ferrs() { | 
|  | 98 | static formatted_raw_ostream S(errs()); | 
|  | 99 | return S; | 
|  | 100 | } | 
| David Greene | 93a522b | 2010-01-05 01:28:43 +0000 | [diff] [blame] | 101 |  | 
|  | 102 | /// fdbgs() - This returns a reference to a formatted_raw_ostream for | 
|  | 103 | /// the debug stream.  Use it like: fdbgs() << "foo" << "bar"; | 
|  | 104 | formatted_raw_ostream &llvm::fdbgs() { | 
|  | 105 | static formatted_raw_ostream S(dbgs()); | 
|  | 106 | return S; | 
|  | 107 | } |