LCOV - code coverage report
Current view: top level - common - mapstrings.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 42 44 95.5 %
Date: 2016-11-29 15:00:56 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* mapstrings.c - Static string mapping
       2             :  * Copyright (C) 2014 Werner Koch
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       6             :  * This file is free software; you can redistribute it and/or modify
       7             :  * it under the terms of either
       8             :  *
       9             :  *   - the GNU Lesser General Public License as published by the Free
      10             :  *     Software Foundation; either version 3 of the License, or (at
      11             :  *     your option) any later version.
      12             :  *
      13             :  * or
      14             :  *
      15             :  *   - the GNU General Public License as published by the Free
      16             :  *     Software Foundation; either version 2 of the License, or (at
      17             :  *     your option) any later version.
      18             :  *
      19             :  * or both in parallel, as here.
      20             :  *
      21             :  * This file is distributed in the hope that it will be useful,
      22             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      23             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      24             :  * GNU General Public License for more details.
      25             :  *
      26             :  * You should have received a copy of the GNU General Public License
      27             :  * along with this program; if not, see <https://www.gnu.org/licenses/>.
      28             :  */
      29             : 
      30             : #include <config.h>
      31             : #include <stdlib.h>
      32             : #include <errno.h>
      33             : 
      34             : #include "util.h"
      35             : #include "stringhelp.h"
      36             : #include "membuf.h"
      37             : 
      38             : 
      39             : static struct {
      40             :   const char *name;
      41             :   const char *value;
      42             : } macros[] = {
      43             : #ifdef PACKAGE_BUGREPORT
      44             :   { "EMAIL", PACKAGE_BUGREPORT },
      45             : #else
      46             :   { "EMAIL", "bug@example.org" },
      47             : #endif
      48             :   { "GNUPG",     GNUPG_NAME },
      49             :   { "GPG",       GPG_NAME },
      50             :   { "GPGSM",     GPGSM_NAME },
      51             :   { "GPG_AGENT", GPG_AGENT_NAME },
      52             :   { "SCDAEMON",  SCDAEMON_NAME },
      53             :   { "DIRMNGR",   DIRMNGR_NAME },
      54             :   { "G13",       G13_NAME },
      55             :   { "GPGCONF",   GPGCONF_NAME },
      56             :   { "GPGTAR",    GPGTAR_NAME }
      57             : };
      58             : 
      59             : 
      60             : 
      61             : /* A list to remember already done mappings.  */
      62             : struct mapping_s
      63             : {
      64             :   struct mapping_s *next;
      65             :   const char *key;
      66             :   const char *value;
      67             : };
      68             : static struct mapping_s *mappings;
      69             : 
      70             : 
      71             : /* If STRING has already been mapped, return the mapped string.  If
      72             :    not return NULL.  */
      73             : static const char *
      74         786 : already_mapped (const char *string)
      75             : {
      76             :   struct mapping_s *m;
      77             : 
      78         971 :   for (m=mappings; m; m = m->next)
      79         197 :     if (m->key == string && !strcmp (m->key, string))
      80          12 :       return m->value;
      81         774 :   return NULL;
      82             : }
      83             : 
      84             : 
      85             : /* Store NEWSTRING under key STRING and return NEWSTRING.  */
      86             : static const char *
      87          67 : store_mapping (const char *string, char *newstring)
      88             : {
      89             :   struct mapping_s *m;
      90             : 
      91          67 :   m = xmalloc (sizeof *m);
      92          67 :   m->key = string;
      93          67 :   m->value = newstring;
      94          67 :   m->next = mappings;
      95          67 :   mappings = m;
      96          67 :   return newstring;
      97             : }
      98             : 
      99             : 
     100             : /* Find the first macro in STRING.  Return a pointer to the
     101             :    replacement value, set BEGPTR to the leading '@', and set ENDPTR to
     102             :    the terminating '@'.  If no macro is found return NULL.  */
     103             : const char *
     104         901 : find_macro (const char *string,  const char **begptr,
     105             :             const char **endptr)
     106             : {
     107             :   const char *s, *s2, *s3;
     108             :   int idx;
     109             : 
     110         901 :   s = string;
     111         901 :   if (!s)
     112           0 :     return NULL;
     113             : 
     114         939 :   for (; (s2 = strchr (s, '@')); s = s2)
     115             :     {
     116         165 :       s2++;
     117         165 :       if (*s2 >= 'A' && *s2 <= 'Z' && (s3 = (strchr (s2, '@'))))
     118             :         {
     119         447 :           for (idx=0; idx < DIM (macros); idx++)
     120         447 :             if (strlen (macros[idx].name) == (s3 - s2)
     121         188 :                 && !memcmp (macros[idx].name, s2, (s3 - s2)))
     122             :               {
     123         127 :                 *begptr = s2 - 1;
     124         127 :                 *endptr = s3;
     125         127 :                 return macros[idx].value;
     126             :               }
     127             :         }
     128             :     }
     129         774 :   return NULL;
     130             : }
     131             : 
     132             : 
     133             : /* If STRING includes known @FOO@ macros, replace these macros and
     134             :    return a new static string.  Warning: STRING must have been
     135             :    allocated statically.  Note that this function allocates memory
     136             :    which will not be released (similar to gettext).  */
     137             : const char *
     138         786 : map_static_macro_string (const char *string)
     139             : {
     140             :   const char *s, *s2, *s3, *value;
     141             :   membuf_t mb;
     142             :   char *p;
     143             : 
     144         786 :   if ((s = already_mapped (string)))
     145          12 :     return s;
     146         774 :   s = string;
     147         774 :   value = find_macro (s, &s2, &s3);
     148         774 :   if (!value)
     149         707 :     return string; /* No macros at all.  */
     150             : 
     151          67 :   init_membuf (&mb, strlen (string) + 100);
     152             :   do
     153             :     {
     154         127 :       put_membuf (&mb, s, s2 - s);
     155         127 :       put_membuf_str (&mb, value);
     156         127 :       s = s3 + 1;
     157             :     }
     158         127 :   while ((value = find_macro (s, &s2, &s3)));
     159          67 :   put_membuf_str (&mb, s);
     160          67 :   put_membuf (&mb, "", 1);
     161             : 
     162          67 :   p = get_membuf_shrink (&mb, NULL);
     163          67 :   if (!p)
     164           0 :     log_fatal ("map_static_macro_string failed: %s\n", strerror (errno));
     165             : 
     166          67 :   return store_mapping (string, p);
     167             : }

Generated by: LCOV version 1.11