Skip to content

Commit 4becb88

Browse files
committed
automatically format help text to match terminal width
This extends the help formatter used by the CHC encoder to consider the width of the terminal when formatting the command line help. Lines are wrapped on spaces that are encountered in non-highlighted text.
1 parent 7e81905 commit 4becb88

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)