On Wed, 2006-07-19 at 19:01 +0200, Johannes Berg wrote:
Give me a minute, I'm just testing a small patch.
Done. Now you can use %-2.02i and it should work for all lengths, even length 1 :) Timo, it'd be nice if you could apply this :) --- This patch makes it possible to use a negative offset to count from the end of a variable. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> --- dovecot-1.0.rc2/doc/variables.txt 2006-04-12 09:39:31.000000000 +0200 +++ dovecot-1.0.rc2.mod/doc/variables.txt 2006-07-19 19:27:15.611041184 +0200 @@ -35,7 +35,10 @@ You can take a substring of the variable by giving optional offset followed by '.' and width after the '%' character. For example %2u gives first two characters of the username. %2.1u gives third character of the username. If -offset points outside the value, empty string is returned. +the offset is negative, it counts from the end, for example %-2.02i gives +the UID mod 100 (last two characters of the UID printed in a string). If a +positive offset points outside the value, empty string is returned, if a +negative offset does then the string is taken from the start. For login_log_format_elements there are also these variables: --- dovecot-1.0.rc2/src/lib/var-expand.c 2006-04-12 09:39:32.000000000 +0200 +++ dovecot-1.0.rc2.mod/src/lib/var-expand.c 2006-07-19 19:11:14.661041184 +0200 @@ -11,7 +11,8 @@ #include <stdlib.h> struct var_expand_context { - unsigned int offset, width; + int offset; + unsigned int width; }; struct var_expand_modifier { @@ -108,7 +109,7 @@ struct var_expand_context ctx; const char *(*modifier[MAX_MODIFIER_COUNT]) (const char *, struct var_expand_context *); - unsigned int i, modifier_count; + unsigned int i, modifier_count, sign = 1; bool zero_padding = FALSE; memset(&ctx, 0, sizeof(ctx)); @@ -120,12 +121,16 @@ /* [<offset>.]<width>[<modifiers>]<variable> */ ctx.width = 0; + if (*str == '-') { + sign = -1; + str++; + } if (*str == '0') { zero_padding = TRUE; str++; } while (*str >= '0' && *str <= '9') { - ctx.width = ctx.width*10 + (*str - '0'); + ctx.width = ctx.width*10 + sign * (*str - '0'); str++; } @@ -178,9 +183,21 @@ if (var != NULL) { for (i = 0; i < modifier_count; i++) var = modifier[i](var, &ctx); - while (*var != '\0' && ctx.offset > 0) { - ctx.offset--; - var++; + if (ctx.offset < 0) { + /* if offset is < 0 then we want to + * start at the end */ + size_t len = strlen(var); + var += len; /* point to trailing NUL byte */ + while (ctx.offset < 0 && len > 0) { + ctx.offset++; + var--; + len--; + } + } else { + while (*var != '\0' && ctx.offset > 0) { + ctx.offset--; + var++; + } } if (ctx.width == 0) str_append(dest, var); @@ -205,7 +222,7 @@ const struct var_expand_modifier *m; /* [<offset>.]<width>[<modifiers>]<variable> */ - while (*str >= '0' && *str <= '9') + while ((*str >= '0' && *str <= '9') || *str == '-') str++; if (*str == '.') {