Mercurial > dovecot > core-2.2
changeset 4558:fc58084df7b5 HEAD
Negative offsets count from the end of the string. Patch by Johannes Berg.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 10 Aug 2006 23:22:40 +0300 |
parents | 3da066d844ea |
children | 4d2c4bb02c81 |
files | doc/variables.txt src/lib/var-expand.c |
diffstat | 2 files changed, 27 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/variables.txt Thu Aug 10 22:44:19 2006 +0300 +++ b/doc/variables.txt Thu Aug 10 23:22:40 2006 +0300 @@ -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:
--- a/src/lib/var-expand.c Thu Aug 10 22:44:19 2006 +0300 +++ b/src/lib/var-expand.c Thu Aug 10 23:22:40 2006 +0300 @@ -11,7 +11,8 @@ #include <stdlib.h> struct var_expand_context { - unsigned int offset, width; + int offset; + unsigned int width; }; struct var_expand_modifier { @@ -71,7 +72,7 @@ } str_printfa(hash, "%x", value); - while (str_len(hash) < ctx->offset) + while ((int)str_len(hash) < ctx->offset) str_insert(hash, 0, "0"); ctx->offset = 0; @@ -109,6 +110,7 @@ const char *(*modifier[MAX_MODIFIER_COUNT]) (const char *, struct var_expand_context *); unsigned int i, modifier_count; + int sign = 1; bool zero_padding = FALSE; memset(&ctx, 0, sizeof(ctx)); @@ -120,6 +122,10 @@ /* [<offset>.]<width>[<modifiers>]<variable> */ ctx.width = 0; + if (*str == '-') { + sign = -1; + str++; + } if (*str == '0') { zero_padding = TRUE; str++; @@ -132,7 +138,7 @@ if (*str != '.') ctx.offset = 0; else { - ctx.offset = ctx.width; + ctx.offset = sign * (int)ctx.width; ctx.width = 0; str++; while (*str >= '0' && *str <= '9') { @@ -178,9 +184,19 @@ 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); + + if (len > (size_t)-ctx.offset) + var += len + ctx.offset; + } else { + while (*var != '\0' && ctx.offset > 0) { + ctx.offset--; + var++; + } } if (ctx.width == 0) str_append(dest, var); @@ -205,7 +221,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 == '.') {