LCOV - code coverage report
Current view: top level - basic - replace-var.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 41 48 85.4 %
Date: 2019-08-22 15:41:25 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <errno.h>
       4             : #include <stddef.h>
       5             : #include <stdlib.h>
       6             : #include <string.h>
       7             : 
       8             : #include "alloc-util.h"
       9             : #include "macro.h"
      10             : #include "replace-var.h"
      11             : #include "string-util.h"
      12             : 
      13             : /*
      14             :  * Generic infrastructure for replacing @FOO@ style variables in
      15             :  * strings. Will call a callback for each replacement.
      16             :  */
      17             : 
      18          42 : static int get_variable(const char *b, char **r) {
      19             :         size_t k;
      20             :         char *t;
      21             : 
      22          42 :         assert(b);
      23          42 :         assert(r);
      24             : 
      25          42 :         if (*b != '@')
      26          30 :                 return 0;
      27             : 
      28          12 :         k = strspn(b + 1, UPPERCASE_LETTERS "_");
      29          12 :         if (k <= 0 || b[k+1] != '@')
      30          10 :                 return 0;
      31             : 
      32           2 :         t = strndup(b + 1, k);
      33           2 :         if (!t)
      34           0 :                 return -ENOMEM;
      35             : 
      36           2 :         *r = t;
      37           2 :         return 1;
      38             : }
      39             : 
      40           1 : char *replace_var(const char *text, char *(*lookup)(const char *variable, void *userdata), void *userdata) {
      41             :         char *r, *t;
      42             :         const char *f;
      43             :         size_t l;
      44             : 
      45           1 :         assert(text);
      46           1 :         assert(lookup);
      47             : 
      48           1 :         l = strlen(text);
      49           1 :         r = new(char, l+1);
      50           1 :         if (!r)
      51           0 :                 return NULL;
      52             : 
      53           1 :         f = text;
      54           1 :         t = r;
      55          43 :         while (*f) {
      56          82 :                 _cleanup_free_ char *v = NULL, *n = NULL;
      57             :                 char *a;
      58             :                 int k;
      59             :                 size_t skip, d, nl;
      60             : 
      61          42 :                 k = get_variable(f, &v);
      62          42 :                 if (k < 0)
      63           0 :                         goto oom;
      64          42 :                 if (k == 0) {
      65          40 :                         *(t++) = *(f++);
      66          40 :                         continue;
      67             :                 }
      68             : 
      69           2 :                 n = lookup(v, userdata);
      70           2 :                 if (!n)
      71           0 :                         goto oom;
      72             : 
      73           2 :                 skip = strlen(v) + 2;
      74             : 
      75           2 :                 d = t - r;
      76           2 :                 nl = l - skip + strlen(n);
      77           2 :                 a = realloc(r, nl + 1);
      78           2 :                 if (!a)
      79           0 :                         goto oom;
      80             : 
      81           2 :                 l = nl;
      82           2 :                 r = a;
      83           2 :                 t = r + d;
      84             : 
      85           2 :                 t = stpcpy(t, n);
      86           2 :                 f += skip;
      87             :         }
      88             : 
      89           1 :         *t = 0;
      90           1 :         return r;
      91             : 
      92           0 : oom:
      93           0 :         return mfree(r);
      94             : }

Generated by: LCOV version 1.14