[Dovecot] [PATCH]

Johannes Berg johannes at sipsolutions.net
Wed Jul 19 20:38:12 EEST 2006


This patch makes it possible to use a negative offset to count from the
end of a variable.

Signed-off-by: Johannes Berg <johannes at 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:35:25.821041184 +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 {
@@ -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 == '.') {




More information about the dovecot mailing list