mirror of
https://codeberg.org/dnkl/yambar.git
synced 2025-04-25 05:15:41 +02:00
implement field width tag format option
This implements the possibility of specifying padding for numeric tags. Both space and zero padding is supported.
This commit is contained in:
parent
73ccafdade
commit
146759bd96
3 changed files with 79 additions and 25 deletions
|
@ -12,6 +12,12 @@
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
* field width tag format option ([#246][246])
|
||||||
|
|
||||||
|
[246]: https://codeberg.org/dnkl/yambar/issues/246
|
||||||
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
* disk-io: `interval` renamed to `poll-interval`
|
* disk-io: `interval` renamed to `poll-interval`
|
||||||
|
@ -45,6 +51,7 @@
|
||||||
### Security
|
### Security
|
||||||
### Contributors
|
### Contributors
|
||||||
|
|
||||||
|
* Leonardo Gibrowski Faé (Horus)
|
||||||
|
|
||||||
## 1.9.0
|
## 1.9.0
|
||||||
|
|
||||||
|
|
|
@ -60,10 +60,20 @@ be used.
|
||||||
:[ *Kind*
|
:[ *Kind*
|
||||||
:[ *Description*
|
:[ *Description*
|
||||||
:< *Applies to*
|
:< *Applies to*
|
||||||
|
| [0]<number>[.]
|
||||||
|
: format
|
||||||
|
: The width reserved to the field. The leading '0' is optional and
|
||||||
|
indicates zero padding, as opposed to space padding. The trailing
|
||||||
|
'.' is also optional
|
||||||
|
: Numeric tags (integer and floats)
|
||||||
| .<number>
|
| .<number>
|
||||||
: format
|
: format
|
||||||
: How many decimals to print
|
: How many decimals to print
|
||||||
: Float tags
|
: Float tags
|
||||||
|
| [0]<N>[.]<M>
|
||||||
|
: format
|
||||||
|
: Combined version of the two previous formatters
|
||||||
|
: N: numeric tags, M: float tags
|
||||||
| hex
|
| hex
|
||||||
: format
|
: format
|
||||||
: Renders a tag's value in hex
|
: Renders a tag's value in hex
|
||||||
|
|
87
tag.c
87
tag.c
|
@ -6,6 +6,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include<errno.h>
|
||||||
|
|
||||||
#define LOG_MODULE "tag"
|
#define LOG_MODULE "tag"
|
||||||
#define LOG_ENABLE_DBG 1
|
#define LOG_ENABLE_DBG 1
|
||||||
|
@ -427,13 +428,18 @@ sbuf_append(struct sbuf *s1, const char *s2)
|
||||||
sbuf_append_at_most(s1, s2, strlen(s2));
|
sbuf_append_at_most(s1, s2, strlen(s2));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
// stores the number in "*value" on success
|
||||||
is_number(const char *str) {
|
static bool
|
||||||
while (*str != '\0') {
|
is_number(const char *str, int *value)
|
||||||
if (!isdigit(*str))
|
{
|
||||||
return false;
|
errno = 0;
|
||||||
++str;
|
|
||||||
}
|
char *end;
|
||||||
|
int v = strtol(str, &end, 10);
|
||||||
|
if (errno != 0 || *end != '\0')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*value = v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,8 +525,10 @@ tags_expand_template(const char *template, const struct tag_set *tags)
|
||||||
VALUE_UNIT,
|
VALUE_UNIT,
|
||||||
} kind = VALUE_VALUE;
|
} kind = VALUE_VALUE;
|
||||||
|
|
||||||
|
int digits = 0;
|
||||||
int decimals = 2;
|
int decimals = 2;
|
||||||
char *float_fmt_end;
|
bool zero_pad = false;
|
||||||
|
char *point = NULL;
|
||||||
|
|
||||||
for (size_t i = 0; i < MAX_TAG_ARGS; i++) {
|
for (size_t i = 0; i < MAX_TAG_ARGS; i++) {
|
||||||
if (tag_args[i] == NULL)
|
if (tag_args[i] == NULL)
|
||||||
|
@ -549,8 +557,31 @@ tags_expand_template(const char *template, const struct tag_set *tags)
|
||||||
kind = VALUE_MAX;
|
kind = VALUE_MAX;
|
||||||
else if (strcmp(tag_args[i], "unit") == 0)
|
else if (strcmp(tag_args[i], "unit") == 0)
|
||||||
kind = VALUE_UNIT;
|
kind = VALUE_UNIT;
|
||||||
else if (tag_args[i][0] == '.' && is_number(tag_args[i] + 1))
|
else if (is_number(tag_args[i], &digits)) // i.e.: "{tag:3}"
|
||||||
decimals = strtol(tag_args[i] + 1, &float_fmt_end, 10);
|
zero_pad = tag_args[i][0] == '0';
|
||||||
|
else if ((point = strchr(tag_args[i], '.')) != NULL) {
|
||||||
|
*point = '\0';
|
||||||
|
|
||||||
|
const char *digits_str = tag_args[i];
|
||||||
|
const char *decimals_str = point + 1;
|
||||||
|
|
||||||
|
if (digits_str[0] != '\0') { // guards against i.e. "{tag:.3}"
|
||||||
|
if (!is_number(digits_str, &digits)) {
|
||||||
|
LOG_WARN(
|
||||||
|
"tag `%s`: invalid field width formatter. Ignoring...",
|
||||||
|
tag_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decimals_str[0] != '\0') { // guards against i.e. "{tag:3.}"
|
||||||
|
if (!is_number(decimals_str, &decimals)) {
|
||||||
|
LOG_WARN(
|
||||||
|
"tag `%s`: invalid decimals formatter. Ignoring...",
|
||||||
|
tag_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zero_pad = digits_str[0] == '0';
|
||||||
|
}
|
||||||
else
|
else
|
||||||
LOG_WARN("invalid tag formatter: %s", tag_args[i]);
|
LOG_WARN("invalid tag formatter: %s", tag_args[i]);
|
||||||
}
|
}
|
||||||
|
@ -561,8 +592,9 @@ tags_expand_template(const char *template, const struct tag_set *tags)
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case FMT_DEFAULT: {
|
case FMT_DEFAULT: {
|
||||||
if (tag->type(tag) == TAG_TYPE_FLOAT){
|
if (tag->type(tag) == TAG_TYPE_FLOAT){
|
||||||
|
const char* fmt = zero_pad ? "%0*.*f" : "%*.*f";
|
||||||
char str[24];
|
char str[24];
|
||||||
snprintf(str, sizeof(str), "%.*f", decimals, tag->as_float(tag));
|
snprintf(str, sizeof(str), fmt, digits, decimals, tag->as_float(tag));
|
||||||
sbuf_append(&formatted, str);
|
sbuf_append(&formatted, str);
|
||||||
} else {
|
} else {
|
||||||
sbuf_append(&formatted, tag->as_string(tag));
|
sbuf_append(&formatted, tag->as_string(tag));
|
||||||
|
@ -572,9 +604,11 @@ tags_expand_template(const char *template, const struct tag_set *tags)
|
||||||
|
|
||||||
case FMT_HEX:
|
case FMT_HEX:
|
||||||
case FMT_OCT: {
|
case FMT_OCT: {
|
||||||
|
const char* fmt = format == FMT_HEX ?
|
||||||
|
zero_pad ? "%0*lx" : "%*lx" :
|
||||||
|
zero_pad ? "%0*lo" : "%*lo";
|
||||||
char str[24];
|
char str[24];
|
||||||
snprintf(str, sizeof(str), format == FMT_HEX ? "%lx" : "%lo",
|
snprintf(str, sizeof(str), fmt, digits, tag->as_int(tag));
|
||||||
tag->as_int(tag));
|
|
||||||
sbuf_append(&formatted, str);
|
sbuf_append(&formatted, str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -584,8 +618,9 @@ tags_expand_template(const char *template, const struct tag_set *tags)
|
||||||
const long max = tag->max(tag);
|
const long max = tag->max(tag);
|
||||||
const long cur = tag->as_int(tag);
|
const long cur = tag->as_int(tag);
|
||||||
|
|
||||||
|
const char* fmt = zero_pad ? "%0*lu" : "%*lu";
|
||||||
char str[4];
|
char str[4];
|
||||||
snprintf(str, sizeof(str), "%lu", (cur - min) * 100 / (max - min));
|
snprintf(str, sizeof(str), fmt, digits, (cur - min) * 100 / (max - min));
|
||||||
sbuf_append(&formatted, str);
|
sbuf_append(&formatted, str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -606,10 +641,13 @@ tags_expand_template(const char *template, const struct tag_set *tags)
|
||||||
1;
|
1;
|
||||||
|
|
||||||
char str[24];
|
char str[24];
|
||||||
if (tag->type(tag) == TAG_TYPE_FLOAT)
|
if (tag->type(tag) == TAG_TYPE_FLOAT) {
|
||||||
snprintf(str, sizeof(str), "%.*f", decimals, tag->as_float(tag) / (double)divider);
|
const char* fmt = zero_pad ? "%0*.*f" : "%*.*f";
|
||||||
else
|
snprintf(str, sizeof(str), fmt, digits, decimals, tag->as_float(tag) / (double)divider);
|
||||||
snprintf(str, sizeof(str), "%lu", tag->as_int(tag) / divider);
|
} else {
|
||||||
|
const char* fmt = zero_pad ? "%0*lu" : "%*lu";
|
||||||
|
snprintf(str, sizeof(str), fmt, digits, tag->as_int(tag) / divider);
|
||||||
|
}
|
||||||
sbuf_append(&formatted, str);
|
sbuf_append(&formatted, str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -624,13 +662,12 @@ tags_expand_template(const char *template, const struct tag_set *tags)
|
||||||
|
|
||||||
const char *fmt;
|
const char *fmt;
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case FMT_DEFAULT: fmt = "%ld"; break;
|
case FMT_DEFAULT: fmt = zero_pad ? "%0*ld" : "%*ld"; break;
|
||||||
case FMT_HEX: fmt = "%lx"; break;
|
case FMT_HEX: fmt = zero_pad ? "%0*lx" : "%*lx"; break;
|
||||||
case FMT_OCT: fmt = "%lo"; break;
|
case FMT_OCT: fmt = zero_pad ? "%0*lo" : "%*lo"; break;
|
||||||
|
|
||||||
case FMT_PERCENT:
|
case FMT_PERCENT:
|
||||||
value = (value - min) * 100 / (max - min);
|
value = (value - min) * 100 / (max - min);
|
||||||
fmt = "%lu";
|
fmt = zero_pad ? "%0*lu" : "%*lu";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FMT_KBYTE:
|
case FMT_KBYTE:
|
||||||
|
@ -648,13 +685,13 @@ tags_expand_template(const char *template, const struct tag_set *tags)
|
||||||
format == FMT_GIBYTE ? 1000 * 1000 * 1000 :
|
format == FMT_GIBYTE ? 1000 * 1000 * 1000 :
|
||||||
1;
|
1;
|
||||||
value /= divider;
|
value /= divider;
|
||||||
fmt = "%lu";
|
fmt = zero_pad ? "%0*lu" : "%*lu";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char str[24];
|
char str[24];
|
||||||
snprintf(str, sizeof(str), fmt, value);
|
snprintf(str, sizeof(str), fmt, digits, value);
|
||||||
sbuf_append(&formatted, str);
|
sbuf_append(&formatted, str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue