2023-08-28 12:31:18 +02:00
|
|
|
/* Print fancy tables.
|
2018-08-22 11:29:39 +02:00
|
|
|
*
|
2023-08-31 11:17:07 +02:00
|
|
|
* Author: Steffen Vogel <post@steffenvogel.de>
|
|
|
|
* SPDX-FileCopyrightText: 2014-2023 Institute for Automation of Complex Power Systems, RWTH Aachen University
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
2023-08-28 12:31:18 +02:00
|
|
|
*/
|
2018-08-22 11:29:39 +02:00
|
|
|
|
2019-06-23 16:26:44 +02:00
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstring>
|
2018-08-22 11:29:39 +02:00
|
|
|
|
2019-04-07 15:45:55 +02:00
|
|
|
#include <villas/boxes.hpp>
|
2023-09-07 13:19:19 +02:00
|
|
|
#include <villas/colors.hpp>
|
|
|
|
#include <villas/config.hpp>
|
2021-02-16 14:15:38 +01:00
|
|
|
#include <villas/log.hpp>
|
2023-09-07 13:19:19 +02:00
|
|
|
#include <villas/table.hpp>
|
|
|
|
#include <villas/utils.hpp>
|
2018-08-22 11:29:39 +02:00
|
|
|
|
2021-02-16 14:15:38 +01:00
|
|
|
using namespace villas;
|
2019-05-30 12:43:37 +02:00
|
|
|
using namespace villas::utils;
|
|
|
|
|
2023-04-03 09:42:32 +00:00
|
|
|
#if !defined(LOG_COLOR_DISABLE)
|
2023-09-07 13:19:19 +02:00
|
|
|
#define ANSI_RESET "\e[0m"
|
2023-04-03 09:42:32 +00:00
|
|
|
#else
|
2023-09-07 13:19:19 +02:00
|
|
|
#define ANSI_RESET
|
2023-04-03 09:42:32 +00:00
|
|
|
#endif
|
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
int Table::resize(int w) {
|
|
|
|
int norm, flex, fixed, total;
|
|
|
|
|
|
|
|
width = w;
|
|
|
|
|
|
|
|
norm = 0;
|
|
|
|
flex = 0;
|
|
|
|
fixed = 0;
|
|
|
|
total = width - columns.size() * 2;
|
|
|
|
|
|
|
|
// Normalize width
|
|
|
|
for (unsigned i = 0; i < columns.size(); i++) {
|
|
|
|
if (columns[i].width > 0)
|
|
|
|
norm += columns[i].width;
|
|
|
|
if (columns[i].width == 0)
|
|
|
|
flex++;
|
|
|
|
if (columns[i].width < 0)
|
|
|
|
fixed += -1 * columns[i].width;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < columns.size(); i++) {
|
|
|
|
if (columns[i].width > 0)
|
|
|
|
columns[i]._width = columns[i].width * (float)(total - fixed) / norm;
|
|
|
|
if (columns[i].width == 0)
|
|
|
|
columns[i]._width = (float)(total - fixed) / flex;
|
|
|
|
if (columns[i].width < 0)
|
|
|
|
columns[i]._width = -1 * columns[i].width;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2018-08-22 11:29:39 +02:00
|
|
|
}
|
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
void Table::header() {
|
2024-07-29 12:35:42 +02:00
|
|
|
if (width != Log::getInstance().getWidth())
|
|
|
|
resize(Log::getInstance().getWidth());
|
2023-09-07 13:19:19 +02:00
|
|
|
|
|
|
|
char *line1 = nullptr;
|
|
|
|
char *line2 = nullptr;
|
|
|
|
char *line3 = nullptr;
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < columns.size(); i++) {
|
|
|
|
int w, u;
|
|
|
|
char *col, *unit;
|
|
|
|
|
|
|
|
col = strf(CLR_BLD("%s"), columns[i].title.c_str());
|
|
|
|
unit = columns[i].unit.size() ? strf(CLR_YEL("%s"), columns[i].unit.c_str())
|
|
|
|
: strf("");
|
|
|
|
|
|
|
|
w = columns[i]._width + strlen(col) - strlenp(col);
|
|
|
|
u = columns[i]._width + strlen(unit) - strlenp(unit);
|
|
|
|
|
|
|
|
if (columns[i].align == TableColumn::Alignment::LEFT) {
|
|
|
|
strcatf(&line1, " %-*.*s" ANSI_RESET, w, w, col);
|
|
|
|
strcatf(&line2, " %-*.*s" ANSI_RESET, u, u, unit);
|
|
|
|
} else {
|
|
|
|
strcatf(&line1, " %*.*s" ANSI_RESET, w, w, col);
|
|
|
|
strcatf(&line2, " %*.*s" ANSI_RESET, u, u, unit);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int j = 0; j < columns[i]._width + 2; j++) {
|
|
|
|
strcatf(&line3, "%s", BOX_LR);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i != columns.size() - 1) {
|
|
|
|
strcatf(&line1, " %s", BOX_UD);
|
|
|
|
strcatf(&line2, " %s", BOX_UD);
|
|
|
|
strcatf(&line3, "%s", BOX_UDLR);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(col);
|
|
|
|
free(unit);
|
|
|
|
}
|
|
|
|
|
|
|
|
logger->info("{}", line1);
|
|
|
|
logger->info("{}", line2);
|
|
|
|
logger->info("{}", line3);
|
|
|
|
|
|
|
|
free(line1);
|
|
|
|
free(line2);
|
|
|
|
free(line3);
|
2018-08-22 11:29:39 +02:00
|
|
|
}
|
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
void Table::row(int count, ...) {
|
2024-07-29 12:35:42 +02:00
|
|
|
if (width != Log::getInstance().getWidth()) {
|
|
|
|
resize(Log::getInstance().getWidth());
|
2023-09-07 13:19:19 +02:00
|
|
|
header();
|
|
|
|
}
|
2018-08-22 11:29:39 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
va_list args;
|
|
|
|
va_start(args, count);
|
2018-08-22 11:29:39 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
char *line = nullptr;
|
2018-08-22 11:29:39 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
for (unsigned i = 0; i < columns.size(); ++i) {
|
|
|
|
char *col = vstrf(columns[i].format.c_str(), args);
|
2018-08-22 11:29:39 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
int l = strlenp(col);
|
|
|
|
int r = strlen(col);
|
|
|
|
int w = columns[i]._width + r - l;
|
2018-08-22 11:29:39 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
if (columns[i].align == TableColumn::Alignment::LEFT)
|
|
|
|
strcatf(&line, " %-*.*s " ANSI_RESET, w, w, col);
|
|
|
|
else
|
|
|
|
strcatf(&line, " %*.*s " ANSI_RESET, w, w, col);
|
2019-01-23 02:50:00 +01:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
if (i != columns.size() - 1)
|
|
|
|
strcatf(&line, BOX_UD);
|
2018-08-22 11:29:39 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
free(col);
|
|
|
|
}
|
2018-08-22 11:29:39 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
va_end(args);
|
2018-08-22 11:29:39 +02:00
|
|
|
|
2023-09-07 13:19:19 +02:00
|
|
|
logger->info("{}", line);
|
|
|
|
free(line);
|
2018-08-22 11:29:39 +02:00
|
|
|
}
|