From f33d3ec1d7521c91da8b30ad5cb345d6416bb07d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 12 Apr 2012 01:51:49 +0200 Subject: move more common files to shared/ and add them to shared.la --- src/shared/specifier.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/shared/specifier.c (limited to 'src/shared/specifier.c') diff --git a/src/shared/specifier.c b/src/shared/specifier.c new file mode 100644 index 0000000000..ae00ae10bb --- /dev/null +++ b/src/shared/specifier.c @@ -0,0 +1,108 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "macro.h" +#include "util.h" +#include "specifier.h" + +/* + * Generic infrastructure for replacing %x style specifiers in + * strings. Will call a callback for each replacement. + * + */ + +char *specifier_printf(const char *text, const Specifier table[], void *userdata) { + char *r, *t; + const char *f; + bool percent = false; + size_t l; + + assert(text); + assert(table); + + l = strlen(text); + if (!(r = new(char, l+1))) + return NULL; + + t = r; + + for (f = text; *f; f++, l--) { + + if (percent) { + if (*f == '%') + *(t++) = '%'; + else { + const Specifier *i; + + for (i = table; i->specifier; i++) + if (i->specifier == *f) + break; + + if (i->lookup) { + char *n, *w; + size_t k, j; + + if (!(w = i->lookup(i->specifier, i->data, userdata))) { + free(r); + return NULL; + } + + j = t - r; + k = strlen(w); + + if (!(n = new(char, j + k + l + 1))) { + free(r); + free(w); + return NULL; + } + + memcpy(n, r, j); + memcpy(n + j, w, k); + + free(r); + free(w); + + r = n; + t = n + j + k; + } else { + *(t++) = '%'; + *(t++) = *f; + } + } + + percent = false; + } else if (*f == '%') + percent = true; + else + *(t++) = *f; + } + + *t = 0; + return r; +} + +/* Generic handler for simple string replacements */ + +char* specifier_string(char specifier, void *data, void *userdata) { + return strdup(strempty(data)); +} -- cgit v1.2.3-54-g00ecf From 7ae03f3697762548e49abb6be5ae7151b1ab9365 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 14 Nov 2012 22:15:35 +0100 Subject: specifier: minor modernizations --- src/shared/specifier.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/shared/specifier.c') diff --git a/src/shared/specifier.c b/src/shared/specifier.c index ae00ae10bb..599027cd47 100644 --- a/src/shared/specifier.c +++ b/src/shared/specifier.c @@ -41,7 +41,8 @@ char *specifier_printf(const char *text, const Specifier table[], void *userdata assert(table); l = strlen(text); - if (!(r = new(char, l+1))) + r = new(char, l+1); + if (!r) return NULL; t = r; @@ -62,7 +63,8 @@ char *specifier_printf(const char *text, const Specifier table[], void *userdata char *n, *w; size_t k, j; - if (!(w = i->lookup(i->specifier, i->data, userdata))) { + w = i->lookup(i->specifier, i->data, userdata); + if (!w) { free(r); return NULL; } @@ -70,7 +72,8 @@ char *specifier_printf(const char *text, const Specifier table[], void *userdata j = t - r; k = strlen(w); - if (!(n = new(char, j + k + l + 1))) { + n = new(char, j + k + l + 1); + if (!n) { free(r); free(w); return NULL; -- cgit v1.2.3-54-g00ecf