LCOV - code coverage report
Current view: top level - basic - replace-var.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 41 48 85.4 %
Date: 2019-08-23 13:36:53 Functions: 2 2 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 22 34 64.7 %

           Branch data     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                 :        168 : static int get_variable(const char *b, char **r) {
      19                 :            :         size_t k;
      20                 :            :         char *t;
      21                 :            : 
      22         [ -  + ]:        168 :         assert(b);
      23         [ -  + ]:        168 :         assert(r);
      24                 :            : 
      25         [ +  + ]:        168 :         if (*b != '@')
      26                 :        120 :                 return 0;
      27                 :            : 
      28                 :         48 :         k = strspn(b + 1, UPPERCASE_LETTERS "_");
      29   [ +  +  -  + ]:         48 :         if (k <= 0 || b[k+1] != '@')
      30                 :         40 :                 return 0;
      31                 :            : 
      32                 :          8 :         t = strndup(b + 1, k);
      33         [ -  + ]:          8 :         if (!t)
      34                 :          0 :                 return -ENOMEM;
      35                 :            : 
      36                 :          8 :         *r = t;
      37                 :          8 :         return 1;
      38                 :            : }
      39                 :            : 
      40                 :          4 : 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         [ -  + ]:          4 :         assert(text);
      46         [ -  + ]:          4 :         assert(lookup);
      47                 :            : 
      48                 :          4 :         l = strlen(text);
      49                 :          4 :         r = new(char, l+1);
      50         [ -  + ]:          4 :         if (!r)
      51                 :          0 :                 return NULL;
      52                 :            : 
      53                 :          4 :         f = text;
      54                 :          4 :         t = r;
      55         [ +  + ]:        172 :         while (*f) {
      56   [ +  -  +  +  :        328 :                 _cleanup_free_ char *v = NULL, *n = NULL;
                   -  + ]
      57                 :            :                 char *a;
      58                 :            :                 int k;
      59                 :            :                 size_t skip, d, nl;
      60                 :            : 
      61                 :        168 :                 k = get_variable(f, &v);
      62         [ -  + ]:        168 :                 if (k < 0)
      63                 :          0 :                         goto oom;
      64         [ +  + ]:        168 :                 if (k == 0) {
      65                 :        160 :                         *(t++) = *(f++);
      66                 :        160 :                         continue;
      67                 :            :                 }
      68                 :            : 
      69                 :          8 :                 n = lookup(v, userdata);
      70         [ -  + ]:          8 :                 if (!n)
      71                 :          0 :                         goto oom;
      72                 :            : 
      73                 :          8 :                 skip = strlen(v) + 2;
      74                 :            : 
      75                 :          8 :                 d = t - r;
      76                 :          8 :                 nl = l - skip + strlen(n);
      77                 :          8 :                 a = realloc(r, nl + 1);
      78         [ -  + ]:          8 :                 if (!a)
      79                 :          0 :                         goto oom;
      80                 :            : 
      81                 :          8 :                 l = nl;
      82                 :          8 :                 r = a;
      83                 :          8 :                 t = r + d;
      84                 :            : 
      85                 :          8 :                 t = stpcpy(t, n);
      86                 :          8 :                 f += skip;
      87                 :            :         }
      88                 :            : 
      89                 :          4 :         *t = 0;
      90                 :          4 :         return r;
      91                 :            : 
      92                 :          0 : oom:
      93                 :          0 :         return mfree(r);
      94                 :            : }

Generated by: LCOV version 1.14