Mercurial > dovecot > original-hg > dovecot-1.2
changeset 2977:4a6788997812 HEAD
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.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 15 Dec 2004 22:12:31 +0200 |
parents | 96a4ab34c8f1 |
children | 982e7432276f |
files | src/lib/var-expand.c |
diffstat | 1 files changed, 55 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/var-expand.c Wed Dec 15 22:05:15 2004 +0200 +++ b/src/lib/var-expand.c Wed Dec 15 22:12:31 2004 +0200 @@ -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++; + 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; }