From: Tiago Cunha Date: Sun, 13 May 2012 22:15:11 +0000 (+0100) Subject: Support maximum length in the character pairs. X-Git-Tag: SPECTRWM_1_1_0~22 X-Git-Url: https://code.delx.au/spectrwm/commitdiff_plain/98fcba2bdb01c5950e75ce37fba4a42ea88f8031 Support maximum length in the character pairs. The specified length is used to limit the number of characters outputted by the sequence. Thus, it's now possible to limit, for instance, the window name length. This fixes Flyspray bug #243. --- diff --git a/spectrwm.1 b/spectrwm.1 index 1d14842..399b5a1 100644 --- a/spectrwm.1 +++ b/spectrwm.1 @@ -126,6 +126,8 @@ It may contain the following character sequences: .It Li "++" Ta "A literal" Ql + .El .Pp +All character sequences may limit its output to a specific length, for example ++64A. Any characters that don't match the specification are copied as-is. .It Ic bar_justify Justify the status bar text. Possible values are diff --git a/spectrwm.c b/spectrwm.c index abf3d20..51f2f9a 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -1479,70 +1479,109 @@ bar_fmt(char *fmtexp, char *fmtnew, struct swm_region *r, size_t sz) } /* replaces the bar format character sequences (like in tmux(1)) */ +char * +bar_replace_seq(char *fmt, char *fmtrep, struct swm_region *r, size_t *offrep, + size_t sz) +{ + char *ptr; + char num[8], tmp[SWM_BAR_MAX]; + int limit; + size_t len, numoff = 0; + + /* reset strlcat(3) buffer */ + *tmp = '\0'; + + /* get number, if any */ + fmt++; + while (*fmt != '\0' && isdigit((unsigned char) *fmt)) { + if (numoff >= sizeof num - 1) + break; + num[numoff++] = *fmt++; + } + num[numoff] = '\0'; + + if ((limit = strtonum(num, 1, sizeof tmp - 1, NULL)) == 0) + limit = sizeof tmp - 1; + + /* if number is too big, skip to the first non-digit */ + if (numoff >= sizeof num - 1) { + while (*fmt != '\0' && isdigit((unsigned char) *fmt)) + fmt++; + } + /* there is nothing to replace (ie EOL) */ + if (*fmt == '\0') + return (fmt); + + switch (*fmt) { + case 'A': + snprintf(tmp, sizeof tmp, "%s", bar_ext); + break; + case 'C': + bar_class_name(tmp, sizeof tmp, r); + break; + case 'D': + bar_workspace_name(tmp, sizeof tmp, r); + break; + case 'I': + snprintf(tmp, sizeof tmp, "%d", r->ws->idx + 1); + break; + case 'N': + snprintf(tmp, sizeof tmp, "%d", r->s->idx + 1); + break; + case 'S': + snprintf(tmp, sizeof tmp, "%s", r->ws->stacker); + break; + case 'T': + bar_title_name(tmp, sizeof tmp, r); + break; + case 'U': + bar_urgent(tmp, sizeof tmp); + break; + case 'V': + snprintf(tmp, sizeof tmp, "%s", bar_vertext); + break; + case 'W': + bar_window_name(tmp, sizeof tmp, r); + break; + default: + /* unknown character sequence; copy as-is */ + snprintf(tmp, sizeof tmp, "+%c", *fmt); + break; + } + + len = strlen(tmp); + ptr = tmp; + if (len < limit) + limit = len; + while (limit-- > 0) { + if (*offrep >= sz - 1) + break; + fmtrep[(*offrep)++] = *ptr++; + } + + fmt++; + return (fmt); +} + void bar_replace(char *fmt, char *fmtrep, struct swm_region *r, size_t sz) { - char *ptr; - char tmp[SWM_BAR_MAX]; size_t off; off = 0; - ptr = fmt; - while (*ptr != '\0') { - if (*ptr != '+') { + while (*fmt != '\0') { + if (*fmt != '+') { /* skip ordinary characters */ if (off >= sz - 1) break; - fmtrep[off++] = *ptr++; + fmtrep[off++] = *fmt++; continue; } /* character sequence found; replace it */ - *tmp = '\0'; - - switch (*++ptr) { - case 'A': - snprintf(tmp, sizeof tmp, "%s", bar_ext); - break; - case 'C': - bar_class_name(tmp, sizeof tmp, r); - break; - case 'D': - bar_workspace_name(tmp, sizeof tmp, r); - break; - case 'I': - snprintf(tmp, sizeof tmp, "%d", r->ws->idx + 1); - break; - case 'N': - snprintf(tmp, sizeof tmp, "%d", r->s->idx + 1); + fmt = bar_replace_seq(fmt, fmtrep, r, &off, sz); + if (off >= sz - 1) break; - case 'S': - snprintf(tmp, sizeof tmp, "%s", r->ws->stacker); - break; - case 'T': - bar_title_name(tmp, sizeof tmp, r); - break; - case 'U': - bar_urgent(tmp, sizeof tmp); - break; - case 'V': - snprintf(tmp, sizeof tmp, "%s", bar_vertext); - break; - case 'W': - bar_window_name(tmp, sizeof tmp, r); - break; - default: - /* unknown character sequence; copy as-is */ - snprintf(tmp, sizeof tmp, "+%c", *ptr); - break; - } - - off += snprintf(fmtrep + off, sz - off, "%s", tmp); - if (off >= sz - 1) { - off = sz; - break; - } - ptr++; } fmtrep[off] = '\0';