commit 4327c2ffa9921df30491d6795baef56ef2e00589
parent bd2e6dcd075755d45971281ae4ffb0d2c2fad364
Author: hhvn <dev@hhvn.uk>
Date: Wed, 8 Jun 2022 17:45:06 +0100
Fix format() if clen[PARSE_LEFT] < divlen
Diffstat:
M | src/format.y | | | 60 | +++++++++++++++++++++++++++++++++--------------------------- |
1 file changed, 33 insertions(+), 27 deletions(-)
diff --git a/src/format.y b/src/format.y
@@ -19,7 +19,6 @@ static int yylex(void);
#define RETURN(s) do {prev = s; return s;} while (0)
#define ISSPECIAL(s) isspecial(s, prev, bracelvl, bracetype, styleseg)
-
enum {
PARSE_TIME,
PARSE_LEFT,
@@ -33,6 +32,7 @@ static char *parse_out[PARSE_LAST] = {NULL, NULL, NULL};
static int parse_pos = PARSE_LEFT;
static char **parse_params = NULL;
static struct Server *parse_server = NULL;
+static int parse_divbool = 0;
enum {
var_raw,
@@ -134,14 +134,14 @@ style: STYLE LBRACE STRING RBRACE {
} else if (strcmp($3, "=") == 0) {
if (parse_pos == PARSE_LEFT) {
parse_pos = PARSE_RIGHT;
- $$ = parse_dup("");
+ $$ = NULL;
} else {
$$ = parse_dup(" ");
}
} else if (strcmp($3, "_time") == 0) { /* special style to mark end of timestamp */
if (parse_pos == PARSE_TIME) {
- parse_pos = PARSE_LEFT; /* let's hope no-one puts it in format.ui.timestamp */
- $$ = parse_dup("");
+ parse_pos = parse_divbool ? PARSE_LEFT : PARSE_RIGHT;
+ $$ = NULL;
} else {
yyerror("%{_time} used erroneously here: "
"this style is meant for internal use only, "
@@ -210,7 +210,7 @@ style: STYLE LBRACE STRING RBRACE {
if (strisnum($5, 0) && val) {
$$ = parse_dup(val);
} else if (strisnum($5, 0)) {
- $$ = parse_dup("");
+ $$ = NULL;
} else {
yyerror("first argument to %{split:...} must be an integer");
YYERROR;
@@ -240,6 +240,9 @@ parse_append(char **dest, char *str) {
size_t size;
size_t len;
+ if (!str)
+ return;
+
if (*dest)
len = strlen(*dest);
else
@@ -445,17 +448,6 @@ format(struct Window *window, char *format, struct History *hist) {
format = config_gets(format_get(hist));
assert_warn(format, NULL);
- if (hist && config_getl("timestamp.toggle")) {
- ts = config_gets("format.ui.timestamp");
- len = strlen(ts) + strlen(format) + CONSTLEN("%{_time}") + 1;
- rformat = emalloc(len);
- snprintf(rformat, len, "%s%%{_time}%s", ts, format);
- parse_pos = PARSE_TIME;
- } else {
- rformat = strdup(format);
- parse_pos = PARSE_LEFT;
- }
-
vars[var_channel].val = selected.channel ? selected.channel->name : NULL;
vars[var_topic].val = selected.channel ? selected.channel->topic : NULL;
vars[var_server].val = selected.server ? selected.server->name : NULL;
@@ -496,11 +488,23 @@ format(struct Window *window, char *format, struct History *hist) {
parse_server = NULL;
}
+ if (hist && config_getl("timestamp.toggle")) {
+ ts = config_gets("format.ui.timestamp");
+ len = strlen(ts) + strlen(format) + CONSTLEN("%{_time}") + 1;
+ rformat = emalloc(len);
+ snprintf(rformat, len, "%s%%{_time}%s", ts, format);
+ parse_pos = PARSE_TIME;
+ } else {
+ rformat = strdup(format);
+ parse_pos = divbool ? PARSE_LEFT : PARSE_RIGHT;
+ }
+
parse_dup(0); /* free memory in use for last parse_ */
for (i = 0; i < PARSE_LAST; i++)
pfree(&parse_out[i]);
pfree(&ret);
parse_in = rformat;
+ parse_divbool = divbool;
yyparse();
pfree(&rformat);
@@ -510,13 +514,11 @@ format(struct Window *window, char *format, struct History *hist) {
return NULL;
}
-
- /* If there is no %{=}, then it's on the right */
- if (hist && parse_out[PARSE_LEFT] && !parse_out[PARSE_RIGHT]) {
+ if (parse_out[PARSE_LEFT] && !parse_out[PARSE_RIGHT]) {
parse_out[PARSE_RIGHT] = parse_out[PARSE_LEFT];
parse_out[PARSE_LEFT] = NULL;
}
-
+
for (i = 0; i < PARSE_LAST; i++) {
clen[i] = parse_out[i] ? ui_strlenc(&windows[Win_main], parse_out[i], NULL) : 0;
alen[i] = parse_out[i] ? strlen(parse_out[i]) : 0;
@@ -524,9 +526,13 @@ format(struct Window *window, char *format, struct History *hist) {
/* Space for padding is allocated here (see how len is incremented using pad) */
if (divbool) {
- len = alen[PARSE_TIME] + alen[PARSE_LEFT] + alen[PARSE_RIGHT] + divlen - clen[PARSE_LEFT] + strlen(divstr) + 1;
- pad = clen[PARSE_TIME] + divlen + strlen(divstr) + 1;
- len += (clen[PARSE_RIGHT] / (window->w - pad)) * pad + 1;
+ len = alen[PARSE_TIME] + alen[PARSE_LEFT] + alen[PARSE_RIGHT] + strlen(divstr) + 1;
+ if (clen[PARSE_LEFT] < divlen)
+ len += divlen - clen[PARSE_LEFT];
+ if (window) {
+ pad = clen[PARSE_TIME] + divlen + ui_strlenc(NULL, divstr, NULL) + 1;
+ len += ((clen[PARSE_RIGHT] + 1) / (window->w - pad)) * pad + 1;
+ }
ret = emalloc(len);
snprintf(ret, len, "%1$s %2$*3$s%4$s%5$s",
parse_out[PARSE_TIME] ? parse_out[PARSE_TIME] : "",
@@ -534,15 +540,15 @@ format(struct Window *window, char *format, struct History *hist) {
divstr,
parse_out[PARSE_RIGHT]);
} else {
- len = alen[PARSE_TIME] + alen[PARSE_LEFT] + alen[PARSE_RIGHT] + 1;
+ /* If divbool is zero, then all text is in either PARSE_TIME or PARSE_RIGHT */
+ len = alen[PARSE_TIME] + alen[PARSE_RIGHT] + 1;
if (window) {
pad = clen[PARSE_TIME];
- len += ((clen[PARSE_LEFT] + clen[PARSE_RIGHT] + 1) / (window->w - pad)) * pad;
+ len += ((clen[PARSE_RIGHT] + 1) / (window->w - pad)) * pad;
}
ret = emalloc(len);
- snprintf(ret, len, "%s%s%s",
+ snprintf(ret, len, "%s%s",
parse_out[PARSE_TIME] ? parse_out[PARSE_TIME] : "",
- parse_out[PARSE_LEFT] ? parse_out[PARSE_LEFT] : "",
parse_out[PARSE_RIGHT] ? parse_out[PARSE_RIGHT] : "");
}