[dovecot-cvs] dovecot/src/lib var-expand.c,1.4,1.5

cras at dovecot.org cras at dovecot.org
Wed Dec 15 22:12:34 EET 2004


Update of /var/lib/cvs/dovecot/src/lib
In directory talvi:/tmp/cvs-serv25273

Modified Files:
	var-expand.c 
Log Message:
Added support for multiple modifiers. Added %X = hex modifier. Prefixing
width value with '0' adds '0'-padding to the string if it's smaller than
width.



Index: var-expand.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/var-expand.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- var-expand.c	15 Dec 2004 19:31:06 -0000	1.4
+++ var-expand.c	15 Dec 2004 20:12:31 -0000	1.5
@@ -1,19 +1,31 @@
-/* Copyright (C) 2003 Timo Sirainen */
+/* Copyright (C) 2003-2004 Timo Sirainen */
 
 #include "lib.h"
 #include "str.h"
 #include "strescape.h"
 #include "var-expand.h"
 
+#include <stdlib.h>
+
 struct var_expand_modifier {
 	char key;
 	const char *(*func)(const char *);
 };
 
+static const char *str_hex(const char *str)
+{
+	unsigned long long l;
+
+	l = strtoull(str, NULL, 10);
+	return t_strdup_printf("%llx", l);
+}
+
+#define MAX_MODIFIER_COUNT 10
 static const struct var_expand_modifier modifiers[] = {
 	{ 'L', t_str_lcase },
 	{ 'U', t_str_ucase },
 	{ 'E', str_escape },
+	{ 'X', str_hex },
 	{ '\0', NULL }
 };
 
@@ -24,7 +36,9 @@
         const struct var_expand_table *t;
 	const char *var;
 	unsigned int offset, width;
-	const char *(*modifier)(const char *);
+	const char *(*modifier[MAX_MODIFIER_COUNT])(const char *);
+	unsigned int i, modifier_count;
+	int zero_padding = FALSE;
 
 	for (; *str != '\0'; str++) {
 		if (*str != '%')
@@ -32,8 +46,12 @@
 		else {
 			str++;
 
-			/* [<offset>.]<width>[<modifier>]<variable> */
+			/* [<offset>.]<width>[<modifiers>]<variable> */
 			width = 0;
+			if (*str == '0') {
+				zero_padding = TRUE;
+				str++;
+			}
 			while (*str >= '0' && *str <= '9') {
 				width = width*10 + (*str - '0');
 				str++;
@@ -51,13 +69,21 @@
 				}
 			}
 
-			modifier = NULL;
-			for (m = modifiers; m->key != '\0'; m++) {
-				if (m->key == *str) {
-					modifier = m->func;
-					str++;
-					break;
+                        modifier_count = 0;
+			while (modifier_count < MAX_MODIFIER_COUNT) {
+				modifier[modifier_count] = NULL;
+				for (m = modifiers; m->key != '\0'; m++) {
+					if (m->key == *str) {
+						/* @UNSAFE */
+						modifier[modifier_count] =
+							m->func;
+						str++;
+						break;
+					}
 				}
+				if (modifier[modifier_count] == NULL)
+					break;
+				modifier_count++;
 			}
 
 			if (*str == '\0')
@@ -80,12 +106,21 @@
 			if (var != NULL) {
 				for (; *var != '\0' && offset > 0; offset--)
 					var++;
-				if (modifier != NULL)
-					var = modifier(var);
+				for (i = 0; i < modifier_count; i++)
+					var = modifier[i](var);
 				if (width == 0)
 					str_append(dest, var);
-				else
+				else if (!zero_padding)
 					str_append_n(dest, var, width);
+				else {
+					/* %05d -like padding */
+					size_t len = strlen(var);
+					while (len < width) {
+						str_append_c(dest, '0');
+						width--;
+					}
+					str_append(dest, var);
+				}
 			}
 		}
 	}
@@ -95,7 +130,7 @@
 {
 	const struct var_expand_modifier *m;
 
-	/* [<offset>.]<width>[<modifier>]<variable> */
+	/* [<offset>.]<width>[<modifiers>]<variable> */
 	while (*str >= '0' && *str <= '9')
 		str++;
 
@@ -105,12 +140,14 @@
 			str++;
 	}
 
-	for (m = modifiers; m->key != '\0'; m++) {
-		if (m->key == *str) {
-			str++;
-			break;
+	do {
+		for (m = modifiers; m->key != '\0'; m++) {
+			if (m->key == *str) {
+				str++;
+				break;
+			}
 		}
-	}
+	} while (m->key != '\0');
 
 	return *str;
 }



More information about the dovecot-cvs mailing list