This patch makes it possible to use a negative offset to count from the
end of a variable.
Signed-off-by: Johannes Berg
--- 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:35:25.821041184 +0200
@@ -11,7 +11,8 @@
#include
struct var_expand_context {
- unsigned int offset, width;
+ int offset;
+ unsigned int width;
};
struct var_expand_modifier {
@@ -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,12 +122,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 +184,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 +223,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 == '.') {