Skip to content

Commit cfb192d

Browse files
authored
Merge pull request #7186 from diffblue/help-line-breaks
automatically format help text to match terminal width
2 parents af8e924 + 4becb88 commit cfb192d

File tree

5 files changed

+65
-21
lines changed

5 files changed

+65
-21
lines changed

src/cprover/console.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ class windows_coutt : public std::streambuf
6565
bool consolet::_is_terminal = false;
6666
bool consolet::_use_SGR = false;
6767
bool consolet::_init_done = false;
68+
bool consolet::_width_is_set = false;
69+
std::size_t consolet::_width;
6870
std::ostream *consolet::_out = nullptr;
6971
std::ostream *consolet::_err = nullptr;
7072

@@ -181,15 +183,19 @@ std::ostream &consolet::reset(std::ostream &str)
181183

182184
std::size_t consolet::width()
183185
{
184-
std::size_t width = 80; // default
186+
if(_width_is_set)
187+
return _width;
185188

186-
if(_is_terminal)
189+
_width_is_set = true;
190+
_width = 80; // default
191+
192+
if(is_terminal())
187193
{
188194
#ifdef _WIN32
189195
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
190196
CONSOLE_SCREEN_BUFFER_INFO info;
191197
GetConsoleScreenBufferInfo(h, &info);
192-
width = info.srWindow.Right - info.srWindow.Left + 1;
198+
_width = info.srWindow.Right - info.srWindow.Left + 1;
193199
#else
194200
std::ostringstream width_stream;
195201
run("stty", {"stty", "size"}, "", width_stream, "");
@@ -200,12 +206,12 @@ std::size_t consolet::width()
200206
{
201207
auto width_l = atol(stty_output[1].c_str());
202208
if(width_l >= 10 && width_l <= 400)
203-
width = width_l;
209+
_width = width_l;
204210
}
205211
#endif
206212
}
207213

208-
return width;
214+
return _width;
209215
}
210216

211217
extern "C" int mk_wcwidth(wchar_t ucs);

src/cprover/console.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ class consolet
8282
static bool _is_terminal;
8383
static bool _use_SGR;
8484
static bool _init_done;
85+
static std::size_t _width;
86+
static bool _width_is_set;
8587
static std::ostream *_out;
8688
static std::ostream *_err;
8789
};

src/cprover/cprover_parse_options.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,8 @@ void cprover_parse_optionst::help()
323323
" {bcprover} {usource-file.c} \t convert a given C program\n"
324324
"\n"
325325
"Other options:\n"
326-
" {y--inline} \t perform function call inlining before\n"
327-
" \t generating the formula\n"
326+
" {y--inline} \t perform function call inlining before"
327+
" generating the formula\n"
328328
" {y--no-safety} \t disable safety checks\n"
329329
" {y--contract} {ufunction} \t check contract of given function\n"
330330
" {y--outfile} {ufile-name} \t set output file for formula\n"

src/cprover/help_formatter.cpp

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,23 @@ Author: Daniel Kroening, [email protected]
1212

1313
#include <ostream>
1414

15+
void help_formattert::emit_word(statet &state, std::ostream &out)
16+
{
17+
if(state.word.empty())
18+
return;
19+
20+
// screen width exceeded when aligning?
21+
if(state.column + state.word.size() > consolet::width() && state.aligning)
22+
{
23+
out << '\n' << std::string(first_column_width + 1, ' ');
24+
state.column = first_column_width + 1;
25+
}
26+
27+
out << state.word;
28+
state.column += state.word.size();
29+
state.word.clear();
30+
}
31+
1532
void help_formattert::operator()(std::ostream &out) const
1633
{
1734
std::size_t pos = 0;
@@ -22,15 +39,21 @@ void help_formattert::operator()(std::ostream &out) const
2239
return 0;
2340
};
2441

25-
std::size_t col = 0;
42+
statet state;
2643

2744
while(pos < s.size())
2845
{
2946
auto ch = next();
3047

3148
if(ch == '{')
3249
{
50+
emit_word(state, out);
51+
3352
auto what = next();
53+
// spaces in formatted text are non-breakable
54+
while(pos < s.size() && (ch = next()) != '}')
55+
state.word += ch;
56+
3457
switch(what)
3558
{
3659
case 'b':
@@ -46,31 +69,33 @@ void help_formattert::operator()(std::ostream &out) const
4669
break;
4770
}
4871

49-
while(pos < s.size() && (ch = next()) != '}')
50-
{
51-
out << ch;
52-
col++;
53-
}
54-
72+
emit_word(state, out);
5573
out << consolet::reset;
5674
}
5775
else if(ch == '\t')
5876
{
59-
if(col < 29)
77+
emit_word(state, out);
78+
if(state.column < first_column_width)
6079
{
61-
out << std::string(29 - col, ' ');
62-
col = 40;
80+
out << std::string(first_column_width - state.column, ' ');
81+
state.column = first_column_width;
6382
}
83+
state.aligning = true;
6484
}
6585
else if(ch == '\n')
6686
{
67-
out << ch;
68-
col = 0;
87+
emit_word(state, out);
88+
out << '\n';
89+
state.column = 0;
90+
state.aligning = false;
6991
}
7092
else
7193
{
72-
out << ch;
73-
col++;
94+
state.word += ch;
95+
if(ch == ' ')
96+
emit_word(state, out);
7497
}
7598
}
99+
100+
emit_word(state, out);
76101
}

src/cprover/help_formatter.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@ class help_formattert
2424

2525
const std::string &s;
2626
void operator()(std::ostream &) const;
27+
28+
protected:
29+
struct statet
30+
{
31+
std::size_t column = 0;
32+
bool aligning = false;
33+
std::string word = "";
34+
};
35+
36+
static void emit_word(statet &, std::ostream &);
37+
static const std::size_t first_column_width = 29;
2738
};
2839

2940
static inline help_formattert help_formatter(const std::string &s)

0 commit comments

Comments
 (0)