libzypp: zypp-tui/output/OutNormal.cc Source File

libzypp 17.38.10

OutNormal.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8----------------------------------------------------------------------*/
9
10#include <iostream>
11#include <fstream>
12#include <sstream>
13
14#include <unistd.h>
15
16#include <zypp-core/Pathname.h>
17#include <zypp-core/ByteCount.h> // for download progress reporting
18#include <zypp-core/base/Logger.h>
19#include <zypp-core/base/String.h> // for toUpper()
20#include <zypp-core/base/Gettext.h>
21
22#include <zypp-tui/utils/colors.h>
23#include <zypp-tui/output/AliveCursor.h>
24
25#include "OutNormal.h"
26
27using std::cout;
28using std::cerr;
29using std::endl;
30
31namespace ztui {
32
33OutNormal::OutNormal( Verbosity verbosity_r )
34: Out( TYPE_NORMAL, verbosity_r )
35, _use_colors( false )
36, _isatty( do_ttyout() )
37, _newline( true )
38, _oneup( false )
39{}
40
41OutNormal::~OutNormal()
42{}
43
44 bool OutNormal::mine( Type type )
45{ return( type & Out::TYPE_NORMAL ); }
46
47 bool OutNormal::infoWarningFilter( Verbosity verbosity_r, Type mask )
48{
49 if ( !mine( mask ) )
50 return true;
51 if ( verbosity() < verbosity_r )
52 return true;
53 return false;
54}
55
56 void OutNormal::fixupProgressNL()
57{
58 if ( !_newline ) // An active Progress bar is not NL terminated
59 cout << ansi::tty::clearLN; // Wipe it before writing out a normal line to the screen
60 // Alternative : cout << endl; to Keep the progress bar visible.
61}
62
63 void OutNormal::info( const std::string & msg_r, Verbosity verbosity_r, Type mask )
64{
65 if ( infoWarningFilter( verbosity_r, mask ) )
66 return;
67
68 fixupProgressNL();
69
70 ColorString msg( msg_r, ColorContext::MSG_STATUS );
71 if ( verbosity_r == Out::QUIET )
72 msg = ColorContext::RESULT;
73 else if ( verbosity_r == Out::DEBUG )
74 msg = ColorContext::OSDEBUG;
75
76 cout << msg << endl;
77 _newline = true;
78}
79
80 void OutNormal::infoLine( const TermLine & msg, Verbosity verbosity_r, Type mask )
81{ info( msg.get( termwidth() ), verbosity_r, mask ); }
82
83 void OutNormal::warning( const std::string & msg, Verbosity verbosity_r, Type mask )
84{
85 if ( infoWarningFilter( verbosity_r, mask ) )
86 return;
87
88 fixupProgressNL();
89
90 cout << ( ColorContext::MSG_WARNING << _("Warning: ") ) << msg << endl;
91 _newline = true;
92}
93
94 void OutNormal::error( const std::string & problem_desc, const std::string & hint )
95{
96 fixupProgressNL();
97
98 cerr << ( ColorContext::MSG_ERROR << problem_desc );
99 if ( !hint.empty() && verbosity() > Out::QUIET )
100 cerr << endl << hint;
101 cerr << endl;
102 _newline = true;
103}
104
105// ----------------------------------------------------------------------------
106
107 void OutNormal::error( const zypp::Exception & e, const std::string & problem_desc, const std::string & hint )
108{
109 fixupProgressNL();
110
111 // problem and cause
112 cerr << ( ColorContext::MSG_ERROR << problem_desc << endl << zyppExceptionReport(e) ) << endl;
113
114 // hint
115 if ( !hint.empty() && verbosity() > Out::QUIET )
116 cerr << hint << endl;
117
118 _newline = true;
119}
120
121// ----------------------------------------------------------------------------
122 inline std::ostream & PROGRESS_FLUSH( std::ostream & str ) {
123 static const bool dbg = getenv("ZYPPER_PBD"); // every progress bar redraw on a single line
124 return (dbg ? str << std::endl : str << std::flush );
125}
126
127 void OutNormal::displayProgress ( const std::string & s, int percent )
128{
129 static AliveCursor cursor;
130
131 if ( _isatty )
132 {
133 TermLine outstr( TermLine::SF_CRUSH | TermLine::SF_EXPAND, '-' );
134 outstr.lhs << s << ' ';
135
136 // dont display percents if invalid
137 if ( percent >= 0 && percent <= 100 )
138 {
139 outstr.percentHint = percent;
140 }
141 ++cursor;
142 outstr.rhs << '[' << cursor.current() << ']';
143
144 if ( _oneup )
145 cout << ansi::tty::clearLN << ansi::tty::cursorUP;
146 cout << ansi::tty::clearLN;
147
148 std::string outline( outstr.get( termwidth() ) );
149 cout << outline << PROGRESS_FLUSH;
150 // no _oneup if CRUSHed // _oneup = ( outline.length() > termwidth() );
151 }
152 else
153 cout << '.' << std::flush;
154}
155
156// ----------------------------------------------------------------------------
157
158 void OutNormal::displayTick( const std::string & s )
159{
160 static AliveCursor cursor;
161
162 if ( _isatty )
163 {
164 TermLine outstr( TermLine::SF_CRUSH | TermLine::SF_EXPAND, '-' );
165 ++cursor;
166 outstr.lhs << s << ' ';
167 outstr.rhs << '[' << cursor.current() << ']';
168
169 if( _oneup )
170 cout << ansi::tty::clearLN << ansi::tty::cursorUP;
171 cout << ansi::tty::clearLN;
172
173 std::string outline( outstr.get( termwidth() ) );
174 cout << outline << PROGRESS_FLUSH;
175 // no _oneup if CRUSHed // _oneup = ( outline.length() > termwidth() );
176 }
177 else
178 cout << '.' << std::flush;
179}
180
181// ----------------------------------------------------------------------------
182 void OutNormal::progressStart( const std::string & id, const std::string & label, bool is_tick )
183{
184 if ( progressFilter() )
185 return;
186
187 if ( !_isatty )
188 cout << label << " [";
189
190 if ( is_tick )
191 displayTick( label );
192 else
193 displayProgress( label, 0 );
194
195 _newline = false;
196}
197
198 void OutNormal::progress( const std::string & id, const std::string & label, int value )
199{
200 if (progressFilter())
201 return;
202
203 if (value)
204 displayProgress(label, value);
205 else
206 displayTick(label);
207
208 _newline = false;
209}
210
211 void OutNormal::progressEnd( const std::string & id, const std::string & label, const std::string & donetag, bool error )
212{
213 if ( progressFilter() )
214 return;
215
216 if ( !error && _use_colors )
217 cout << ColorContext::MSG_STATUS;
218
219 TermLine outstr( TermLine::SF_CRUSH | TermLine::SF_EXPAND, '.' );
220 if ( _isatty )
221 {
222 if ( _oneup )
223 {
224 cout << ansi::tty::clearLN << ansi::tty::cursorUP;
225 _oneup = false;
226 }
227 cout << ansi::tty::clearLN;
228
229 outstr.lhs << label << ' ';
230 outstr.rhs << '[';
231 }
232 // else: just write the donetag
233
234 outstr.rhs << donetag << ']';
235
236 std::string outline( outstr.get( termwidth() ) );
237 cout << outline << endl << std::flush;
238 _newline = true;
239
240 if ( !error && _use_colors )
241 cout << ColorContext::DEFAULT;
242}
243
244// progress with download rate
245 void OutNormal::dwnldProgressStart( const zypp::Url & uri )
246{
247 if ( verbosity() < NORMAL )
248 return;
249
250 if ( _isatty )
251 cout << ansi::tty::clearLN;
252
253 TermLine outstr( TermLine::SF_CRUSH | TermLine::SF_EXPAND, '-' );
254 outstr.lhs << _("Retrieving:") << ' ';
255 if ( verbosity() == DEBUG )
256 outstr.lhs << uri;
257 else
258 outstr.lhs << zypp::Pathname(uri.getPathName()).basename();
259 outstr.lhs << ' ';
260 if (_isatty)
261 outstr.rhs << '[' << _("starting") << ']';
262 else
263 outstr.rhs << '[' ;
264
265 std::string outline( outstr.get( termwidth() ) );
266 cout << outline << PROGRESS_FLUSH;
267 // no _oneup if CRUSHed // _oneup = (outline.length() > termwidth());
268
269 _newline = false;
270}
271
272 void OutNormal::dwnldProgress( const zypp::Url & uri, int value, long rate )
273{
274 if ( verbosity() < NORMAL )
275 return;
276
277 if ( !_isatty )
278 {
279 cout << '.' << std::flush;
280 return;
281 }
282
283 if( _oneup )
284 cout << ansi::tty::clearLN << ansi::tty::cursorUP;
285 cout << ansi::tty::clearLN;
286
287 TermLine outstr( TermLine::SF_CRUSH | TermLine::SF_EXPAND, '-' );
288 outstr.lhs << _("Retrieving:") << " ";
289 if ( verbosity() == DEBUG )
290 outstr.lhs << uri;
291 else
292 outstr.lhs << zypp::Pathname(uri.getPathName()).basename();
293 outstr.lhs << ' ';
294
295 // dont display percents if invalid
296 if ( value >= 0 && value <= 100 )
297 outstr.percentHint = value;
298
299 static AliveCursor cursor;
300 ++cursor;
301 outstr.rhs << '[' << cursor.current();
302 if ( rate > 0 )
303 outstr.rhs << " (" << zypp::ByteCount(rate) << "/s)";
304 outstr.rhs << ']';
305
306 std::string outline( outstr.get( termwidth() ) );
307 cout << outline << PROGRESS_FLUSH;
308 // no _oneup if CRUSHed // _oneup = (outline.length() > termwidth());
309 _newline = false;
310}
311
312 void OutNormal::dwnldProgressEnd( const zypp::Url & uri, long rate, zypp::TriBool error )
313{
314 if ( verbosity() < NORMAL )
315 return;
316
317 if ( bool(!error) && _use_colors )
318 cout << ColorContext::MSG_STATUS;
319
320 TermLine outstr( TermLine::SF_CRUSH | TermLine::SF_EXPAND, '.' );
321 if ( _isatty )
322 {
323 if( _oneup )
324 cout << ansi::tty::clearLN << ansi::tty::cursorUP;
325 cout << ansi::tty::clearLN;
326 outstr.lhs << _("Retrieving:") << " ";
327 if ( verbosity() == DEBUG )
328 outstr.lhs << uri;
329 else
330 outstr.lhs << zypp::Pathname(uri.getPathName()).basename();
331 outstr.lhs << ' ';
332 outstr.rhs << '[';
333 if ( zypp::indeterminate( error ) )
334 // Translator: download progress bar result: "........[not found]"
335 outstr.rhs << CHANGEString(_("not found") );
336 else if ( error )
337 // Translator: download progress bar result: "............[error]"
338 outstr.rhs << NEGATIVEString(_("error") );
339 else
340 // Translator: download progress bar result: ".............[done]"
341 outstr.rhs << _("done");
342 }
343 else
344 outstr.rhs << ( zypp::indeterminate( error ) ? _("not found") : ( error ? _("error") : _("done") ) );
345
346 if ( rate > 0 )
347 outstr.rhs << " (" << zypp::ByteCount(rate) << "/s)";
348 outstr.rhs << ']';
349
350 std::string outline( outstr.get( termwidth() ) );
351 cout << outline << endl << std::flush;
352 _newline = true;
353
354 if ( bool(!error) && _use_colors )
355 cout << ColorContext::DEFAULT;
356}
357
358 void OutNormal::prompt( PromptId id, const std::string & prompt, const PromptOptions & poptions, const std::string & startdesc )
359{
360 fixupProgressNL();
361
362 if ( startdesc.empty() )
363 {
364 if ( _isatty )
365 cout << ansi::tty::clearLN;
366 }
367 else
368 cout << startdesc << endl;
369
370 std::ostringstream pstr;
371 ColorStream cout( pstr, ColorContext::PROMPT ); // scoped color on std::cout
372
373 cout << prompt;
374 if ( ! poptions.empty() )
375 cout << text::optBlankAfter(prompt) << ColorString( poptions.optionString() );
376 cout << ": ";
377
378 if ( do_colors() )
379 {
380 // bsc#948566: Terminal is dumb and simply counts the amount of printable
381 // characters. If the number of printable characters within ansi SGR sequences
382 // is not a multiple of 8, tab stops are not computed correctly. We use
383 // superfluous resets ("\033[0m"; 3 printable chars) to fill up.
384 // Better ideas are welcome.
385 size_t invis = 0;
386 bool insgr = false;
387 for ( char ch : pstr.str() )
388 {
389 if ( insgr )
390 {
391 ++invis;
392 if ( ch == 'm' )
393 insgr = false;
394 }
395 else if ( ch == '\033' )
396 insgr = true;
397 }
398 invis %= 8;
399
400 if ( invis )
401 {
402 // "\033[0m" has 3 printable chars:
403 // ( resets[to fill] * 3 ) % 8 == to fill
404 // 0 1 2 3 4 5 6 7
405 static const size_t resets[] = { 0,3,6,1,4,7,2,5 };
406 for ( size_t i = resets[8-invis]; i; --i )
407 cout << ansi::Color::SGRReset();
408 }
409 }
410
411 std::cout << pstr.str() << std::flush;
412 // prompt ends with newline (user hits <enter>) unless exited abnormaly
413 _newline = true;
414}
415
416 void OutNormal::promptHelp( const PromptOptions & poptions )
417{
418 cout << endl;
419
420 if ( poptions.helpEmpty() )
421 cout << _("No help available for this prompt.") << endl;
422
423 // Nevertheless list all option names and their '#NUM' shortcut
424 unsigned pos = 0; // Userland counter #NUM (starts with #1)
425
426 zypp::str::Format fopt { "#%-2d: %-10s" };
427 for ( unsigned idx = 0; idx < poptions.options().size(); ++idx )
428 {
429 if ( poptions.isDisabled(idx) )
430 continue;
431
432 cout << ( fopt % ++pos % poptions.options()[idx] );
433 if ( ! poptions.helpEmpty() )
434 {
435 const std::string & help { poptions.optionHelp(idx) };
436 cout << " - ";
437 if ( help.empty() )
438 cout << ( ColorContext::LOWLIGHT << "(" << _("no help available for this option") << ")" );
439 else
440 cout << help;
441 }
442 cout << endl;
443 }
444
445 ColorStream cout( std::cout, ColorContext::PROMPT ); // scoped color on std::cout
446 cout << endl << ColorString( poptions.optionString() ) << ": " << std::flush;
447 // prompt ends with newline (user hits <enter>) unless exited abnormaly
448 _newline = true;
449}
450
451 unsigned OutNormal::termwidth() const
452{
453 if ( _isatty )
454 {
455 struct winsize wns;
456 if ( !ioctl( 1, TIOCGWINSZ, &wns ) )
457 return wns.ws_col;
458 }
459 return Out::termwidth(); // unlimited
460}
461
462}
AliveCursor.h
ByteCount.h
Gettext.h
_
#define _(MSG)
Definition Gettext.h:39
Logger.h
OutNormal.h
Pathname.h
String.h
ztui::AliveCursor
Definition AliveCursor.h:22
ztui::AliveCursor::current
char current() const
Definition AliveCursor.h:29
ztui::OutNormal::fixupProgressNL
void fixupProgressNL()
Definition OutNormal.cc:56
ztui::OutNormal::displayTick
void displayTick(const std::string &s)
Definition OutNormal.cc:158
ztui::OutNormal::dwnldProgressStart
void dwnldProgressStart(const zypp::Url &uri) override
Reoprt start of a download.
Definition OutNormal.cc:245
ztui::OutNormal::_isatty
bool _isatty
Definition OutNormal.h:66
ztui::OutNormal::error
void error(const std::string &problem_desc, const std::string &hint) override
Show an error message and an optional hint.
Definition OutNormal.cc:94
ztui::OutNormal::OutNormal
OutNormal(Verbosity verbosity=NORMAL)
Definition OutNormal.cc:33
ztui::OutNormal::_use_colors
bool _use_colors
Definition OutNormal.h:65
ztui::OutNormal::progressEnd
void progressEnd(const std::string &id, const std::string &label, const std::string &donetag, bool error) override
End of an operation with reported progress.
Definition OutNormal.cc:211
ztui::OutNormal::prompt
void prompt(PromptId id, const std::string &prompt, const PromptOptions &poptions, const std::string &startdesc) override
Prompt the user for a decision.
Definition OutNormal.cc:358
ztui::OutNormal::displayProgress
void displayProgress(const std::string &s, int percent)
Definition OutNormal.cc:127
ztui::OutNormal::infoLine
void infoLine(const TermLine &msg, Verbosity verbosity, Type mask) override
info taking a TermLine
Definition OutNormal.cc:80
ztui::OutNormal::termwidth
unsigned termwidth() const override
Width for formatted output [0==unlimited].
Definition OutNormal.cc:451
ztui::OutNormal::dwnldProgress
void dwnldProgress(const zypp::Url &uri, int value, long rate) override
Reports download progress.
Definition OutNormal.cc:272
ztui::OutNormal::infoWarningFilter
bool infoWarningFilter(Verbosity verbosity, Type mask)
Definition OutNormal.cc:47
ztui::OutNormal::promptHelp
void promptHelp(const PromptOptions &poptions) override
Print help for prompt, if available.
Definition OutNormal.cc:416
ztui::OutNormal::progressStart
void progressStart(const std::string &id, const std::string &label, bool is_tick) override
Start of an operation with reported progress.
Definition OutNormal.cc:182
ztui::OutNormal::progress
void progress(const std::string &id, const std::string &label, int value) override
Progress report for an on-going operation.
Definition OutNormal.cc:198
ztui::OutNormal::_oneup
bool _oneup
Definition OutNormal.h:71
ztui::OutNormal::warning
void warning(const std::string &msg, Verbosity verbosity, Type mask) override
Show a warning.
Definition OutNormal.cc:83
ztui::OutNormal::~OutNormal
~OutNormal() override
Definition OutNormal.cc:41
ztui::OutNormal::dwnldProgressEnd
void dwnldProgressEnd(const zypp::Url &uri, long rate, zypp::TriBool error) override
Reports end of a download.
Definition OutNormal.cc:312
ztui::OutNormal::_newline
bool _newline
Definition OutNormal.h:69
ztui::OutNormal::mine
bool mine(Type type) override
Determine whether the output is intended for the particular type.
Definition OutNormal.cc:44
ztui::Out::verbosity
Verbosity verbosity() const
Get current verbosity.
Definition Out.h:864
ztui::Out::Out
Out(TypeBit type, Verbosity verbosity=NORMAL)
Definition Out.h:450
ztui::Out::info
Info info()
Definition Out.h:678
ztui::Out::termwidth
virtual unsigned termwidth() const
Width for formatted output [0==unlimited].
Definition Out.h:919
ztui::Out::Verbosity
Verbosity
Verbosity levels.
Definition Out.h:428
ztui::Out::QUIET
@ QUIET
Only important messages (no progress or status, only the result).
Definition Out.h:429
ztui::Out::NORMAL
@ NORMAL
Default output verbosity level.
Definition Out.h:430
ztui::Out::DEBUG
@ DEBUG
Definition Out.h:433
ztui::Out::progressFilter
virtual bool progressFilter()
Determine whether to show progress.
Definition Out.cc:123
ztui::Out::type
TypeBit type() const
Return the type of the instance.
Definition Out.h:895
ztui::Out::zyppExceptionReport
virtual std::string zyppExceptionReport(const zypp::Exception &e)
Return a Exception as a string suitable for output.
Definition Out.cc:128
ztui::Out::PromptId
unsigned PromptId
Definition Out.h:447
ztui::Out::TYPE_NORMAL
@ TYPE_NORMAL
plain text output
Definition Out.h:439
ztui::PromptOptions
Example: PromptOptions popts; popts.setOptions(_("y/n/p"), 0 / * default reply * /); popts....
Definition promptoptions.h:39
ztui::PromptOptions::options
const StrVector & options() const
Definition promptoptions.h:64
ztui::PromptOptions::helpEmpty
bool helpEmpty() const
Definition promptoptions.h:78
ztui::PromptOptions::optionHelp
const std::string & optionHelp(unsigned opt) const
Definition promptoptions.h:74
ztui::PromptOptions::optionString
ColorString optionString() const
Option string (may have embedded color codes).
Definition promptoptions.cc:52
ztui::PromptOptions::isDisabled
bool isDisabled(unsigned opt) const
Definition promptoptions.h:82
ztui::PromptOptions::empty
bool empty() const
Definition promptoptions.h:71
ztui::ansi::ColorStream
Colored stream output if do_colors.
Definition ansi.h:674
ztui::ansi::ColorStream::str
std::string str() const
Return a buffered streams content as (colored) string.
Definition ansi.h:739
ztui::ansi::ColorString
Colored string if do_colors.
Definition ansi.h:497
ztui::ansi::Color::SGRReset
static const std::string & SGRReset()
ANSI SGR sesquence to reset all attributes.
Definition ansi.h:291
zypp::ByteCount
Store and operate with byte count.
Definition ByteCount.h:32
zypp::Exception
Base class for Exception.
Definition Exception.h:153
zypp::Url
Url manipulation class.
Definition Url.h:93
zypp::Url::getPathName
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
Definition Url.cc:631
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:48
zypp::filesystem::Pathname::basename
std::string basename() const
Return the last component of this path.
Definition Pathname.h:137
colors.h
zypp::TriBool
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
Definition String.h:31
str
String related utilities and Regular expression matching.
ztui::ansi::tty::cursorUP
const EscapeSequence cursorUP
Cursor up 1 line.
ztui::ansi::tty::clearLN
const EscapeSequence clearLN
Clear entire line.
ztui::text::optBlankAfter
const char * optBlankAfter(const std::string &str_r)
Definition Out.h:68
ztui
Definition application.cc:13
ztui::NEGATIVEString
CCString< ColorContext::NEGATIVE > NEGATIVEString
Definition colors.h:85
ztui::CHANGEString
CCString< ColorContext::CHANGE > CHANGEString
Definition colors.h:84
ztui::PROGRESS_FLUSH
std::ostream & PROGRESS_FLUSH(std::ostream &str)
Definition OutNormal.cc:122
ztui::ColorContext::MSG_WARNING
@ MSG_WARNING
Definition colors.h:41
ztui::ColorContext::PROMPT
@ PROMPT
Definition colors.h:42
ztui::ColorContext::DEFAULT
@ DEFAULT
Definition colors.h:36
ztui::ColorContext::MSG_ERROR
@ MSG_ERROR
Definition colors.h:40
ztui::ColorContext::OSDEBUG
@ OSDEBUG
Definition colors.h:50
ztui::ColorContext::RESULT
@ RESULT
Definition colors.h:38
ztui::ColorContext::LOWLIGHT
@ LOWLIGHT
Definition colors.h:48
ztui::ColorContext::MSG_STATUS
@ MSG_STATUS
Definition colors.h:39
ztui::do_ttyout
bool do_ttyout()
True unless output is a dumb tty or file.
Definition colors.cc:27
ztui::do_colors
bool do_colors()
If output is done in colors (depends on config).
Definition colors.cc:32
ztui::TermLine
Definition Out.h:343
ztui::TermLine::SF_CRUSH
@ SF_CRUSH
Definition Out.h:346
ztui::TermLine::SF_EXPAND
@ SF_EXPAND
Definition Out.h:348
ztui::TermLine::percentHint
zypp::DefaultIntegral< int,-1 > percentHint
Definition Out.h:359
ztui::TermLine::get
std::string get() const
Return plain line made of lhs + rhs.
Definition Out.h:366
ztui::TermLine::rhs
zypp::str::Str rhs
Definition Out.h:362
ztui::TermLine::lhs
zypp::str::Str lhs
Definition Out.h:361
zypp::str::Format
Convenient building of std::string with boost::format.
Definition String.h:254