Mercurial > dovecot > core-2.2
changeset 3566:0355b805cd4c HEAD
Added 'H' hash modifier.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 01 Sep 2005 10:57:35 +0300 |
parents | 2b167cc13887 |
children | 58e3fa234ef4 |
files | src/lib/var-expand.c |
diffstat | 1 files changed, 69 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/var-expand.c Mon Aug 29 00:28:59 2005 +0300 +++ b/src/lib/var-expand.c Thu Sep 01 10:57:35 2005 +0300 @@ -1,18 +1,42 @@ /* Copyright (C) 2003-2004 Timo Sirainen */ #include "lib.h" +#include "hash.h" #include "str.h" #include "strescape.h" #include "var-expand.h" #include <stdlib.h> +struct var_expand_context { + unsigned int offset, width; +}; + struct var_expand_modifier { char key; - const char *(*func)(const char *); + const char *(*func)(const char *, struct var_expand_context *); }; -static const char *str_hex(const char *str) +static const char * +m_str_lcase(const char *str, struct var_expand_context *ctx __attr_unused__) +{ + return t_str_lcase(str); +} + +static const char * +m_str_ucase(const char *str, struct var_expand_context *ctx __attr_unused__) +{ + return t_str_lcase(str); +} + +static const char * +m_str_escape(const char *str, struct var_expand_context *ctx __attr_unused__) +{ + return str_escape(str); +} + +static const char * +m_str_hex(const char *str, struct var_expand_context *ctx __attr_unused__) { unsigned long long l; @@ -20,12 +44,32 @@ return t_strdup_printf("%llx", l); } +static const char *m_str_hash(const char *str, struct var_expand_context *ctx) +{ + unsigned int value = str_hash(str); + string_t *hash = t_str_new(20); + + if (ctx->width != 0) { + value %= ctx->width; + ctx->width = 0; + } + str_printfa(hash, "%x", value); + while (str_len(hash) < ctx->offset) { + str_insert(hash, 0, "0"); + ctx->offset--; + } + ctx->offset = 0; + + return str_c(hash); +} + #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 }, + { 'L', m_str_lcase }, + { 'U', m_str_ucase }, + { 'E', m_str_escape }, + { 'X', m_str_hex }, + { 'H', m_str_hash }, { '\0', NULL } }; @@ -35,11 +79,13 @@ const struct var_expand_modifier *m; const struct var_expand_table *t; const char *var; - unsigned int offset, width; - const char *(*modifier[MAX_MODIFIER_COUNT])(const char *); + struct var_expand_context ctx; + const char *(*modifier[MAX_MODIFIER_COUNT]) + (const char *, struct var_expand_context *); unsigned int i, modifier_count; int zero_padding = FALSE; + memset(&ctx, 0, sizeof(ctx)); for (; *str != '\0'; str++) { if (*str != '%') str_append_c(dest, *str); @@ -47,24 +93,24 @@ str++; /* [<offset>.]<width>[<modifiers>]<variable> */ - width = 0; + ctx.width = 0; if (*str == '0') { zero_padding = TRUE; str++; } while (*str >= '0' && *str <= '9') { - width = width*10 + (*str - '0'); + ctx.width = ctx.width*10 + (*str - '0'); str++; } if (*str != '.') - offset = 0; + ctx.offset = 0; else { - offset = width; - width = 0; + ctx.offset = ctx.width; + ctx.width = 0; str++; while (*str >= '0' && *str <= '9') { - width = width*10 + (*str - '0'); + ctx.width = ctx.width*10 + (*str - '0'); str++; } } @@ -104,20 +150,22 @@ } if (var != NULL) { - for (; *var != '\0' && offset > 0; offset--) + for (i = 0; i < modifier_count; i++) + var = modifier[i](var, &ctx); + while (*var != '\0' && ctx.offset > 0) { + ctx.offset--; var++; - for (i = 0; i < modifier_count; i++) - var = modifier[i](var); - if (width == 0) + } + if (ctx.width == 0) str_append(dest, var); else if (!zero_padding) - str_append_n(dest, var, width); + str_append_n(dest, var, ctx.width); else { /* %05d -like padding */ size_t len = strlen(var); - while (len < width) { + while (len < ctx.width) { str_append_c(dest, '0'); - width--; + ctx.width--; } str_append(dest, var); }