OR-Tools  9.6
string_util.cc
Go to the documentation of this file.
1 // Copyright 2010-2022 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 #include <algorithm>
15 #include <string>
16 #include <vector>
17 
18 #include "absl/strings/str_format.h"
19 #include "absl/strings/str_join.h"
20 #include "absl/strings/str_split.h"
21 #include "ortools/base/logging.h"
22 
23 namespace operations_research {
24 
25 std::string CropMultiLineString(const std::string& s, int max_line_length,
26  int max_num_lines) {
27  if (s.empty()) return "";
28  std::vector<std::string> lines = absl::StrSplit(s, '\n');
29  DCHECK_GE(lines.size(), 1); // Even an empty string yields one (empty) line.
30  // We ignore the terminating newline for line accounting, but we do output it
31  // back in the end.
32  const bool has_terminating_newline = lines.back().empty();
33  if (has_terminating_newline) lines.pop_back();
34 
35  constexpr char kMultiLineCropTemplate[] = "###% 4d LINES SKIPPED ###";
36  constexpr char kSingleLineCropTemplate[] = " ..[% 4d CHARS CROPPED ].. ";
37  const int single_line_crop_template_length =
38  absl::StrFormat(kSingleLineCropTemplate, 0).size();
39  int num_lines_before = -1;
40  int num_lines_after = -1;
41  int num_lines_cropped = -1;
42  if (lines.size() > max_num_lines) {
43  num_lines_after = (max_num_lines - 1) / 2;
44  // There's a corner case for max_num_lines=0. See the unit test.
45  num_lines_before =
46  max_num_lines == 0 ? 0 : max_num_lines - 1 - num_lines_after;
47  num_lines_cropped = lines.size() - num_lines_before - num_lines_after;
48  lines.erase(lines.begin() + num_lines_before + 1,
49  lines.end() - num_lines_after);
50  // We only fill the special line mentioning the skipped lines after we're
51  // done with the horizontal crops, in the loop below.
52  lines[num_lines_before].clear();
53  }
54  for (std::string& line : lines) {
55  if (line.size() <= max_line_length) continue;
56  const int num_chars_after = std::max(
57  0, static_cast<int>(
58  (max_line_length - single_line_crop_template_length) / 2));
59  const int num_chars_before = std::max(
60  0, static_cast<int>(max_line_length - single_line_crop_template_length -
61  num_chars_after));
62  line = absl::StrCat(
63  line.substr(0, num_chars_before),
64  absl::StrFormat(
65  kSingleLineCropTemplate,
66  static_cast<int>(line.size() - num_chars_after - num_chars_before)),
67  line.substr(line.size() - num_chars_after));
68  }
69  if (num_lines_cropped >= 0) {
70  lines[num_lines_before] =
71  absl::StrFormat(kMultiLineCropTemplate, num_lines_cropped);
72  }
73  if (has_terminating_newline) lines.push_back("");
74  return absl::StrJoin(lines, "\n");
75 }
76 
77 } // namespace operations_research
int64_t max
Definition: alldiff_cst.cc:140
Collection of objects used to extend the Constraint Solver library.
std::string CropMultiLineString(const std::string &s, int max_line_length, int max_num_lines)
Definition: string_util.cc:25
int line
Definition: parse_proto.cc:31