LCOV - code coverage report
Current view: top level - src/common - percentrepl.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 41 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 1 0
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 0.0 % 26 0

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * percentrepl.c
       4                 :             :  *        Common routines to replace percent placeholders in strings
       5                 :             :  *
       6                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :             :  *
       9                 :             :  *
      10                 :             :  * IDENTIFICATION
      11                 :             :  *        src/common/percentrepl.c
      12                 :             :  *
      13                 :             :  *-------------------------------------------------------------------------
      14                 :             :  */
      15                 :             : 
      16                 :             : #ifndef FRONTEND
      17                 :             : #include "postgres.h"
      18                 :             : #else
      19                 :             : #include "postgres_fe.h"
      20                 :             : #include "common/logging.h"
      21                 :             : #endif
      22                 :             : 
      23                 :             : #include "common/percentrepl.h"
      24                 :             : #include "lib/stringinfo.h"
      25                 :             : 
      26                 :             : /*
      27                 :             :  * replace_percent_placeholders
      28                 :             :  *
      29                 :             :  * Replace percent-letter placeholders in input string with the supplied
      30                 :             :  * values.  For example, to replace %f with foo and %b with bar, call
      31                 :             :  *
      32                 :             :  * replace_percent_placeholders(instr, "param_name", "bf", bar, foo);
      33                 :             :  *
      34                 :             :  * The return value is palloc'd.
      35                 :             :  *
      36                 :             :  * "%%" is replaced by a single "%".
      37                 :             :  *
      38                 :             :  * This throws an error for an unsupported placeholder or a "%" at the end of
      39                 :             :  * the input string.
      40                 :             :  *
      41                 :             :  * A value may be NULL.  If the corresponding placeholder is found in the
      42                 :             :  * input string, it will be treated as if an unsupported placeholder was used.
      43                 :             :  * This allows callers to share a "letters" specification but vary the
      44                 :             :  * actually supported placeholders at run time.
      45                 :             :  *
      46                 :             :  * This functions is meant for cases where all the values are readily
      47                 :             :  * available or cheap to compute and most invocations will use most values
      48                 :             :  * (for example for archive_command).  Also, it requires that all values are
      49                 :             :  * strings.  It won't be a good match for things like log prefixes or prompts
      50                 :             :  * that use a mix of data types and any invocation will only use a few of the
      51                 :             :  * possible values.
      52                 :             :  *
      53                 :             :  * param_name is the name of the underlying GUC parameter, for error
      54                 :             :  * reporting.  At the moment, this function is only used for GUC parameters.
      55                 :             :  * If other kinds of uses were added, the error reporting would need to be
      56                 :             :  * revised.
      57                 :             :  */
      58                 :             : char *
      59                 :           0 : replace_percent_placeholders(const char *instr, const char *param_name, const char *letters,...)
      60                 :             : {
      61                 :           0 :         StringInfoData result;
      62                 :             : 
      63                 :           0 :         initStringInfo(&result);
      64                 :             : 
      65         [ #  # ]:           0 :         for (const char *sp = instr; *sp; sp++)
      66                 :             :         {
      67         [ #  # ]:           0 :                 if (*sp == '%')
      68                 :             :                 {
      69         [ #  # ]:           0 :                         if (sp[1] == '%')
      70                 :             :                         {
      71                 :             :                                 /* Convert %% to a single % */
      72                 :           0 :                                 sp++;
      73                 :           0 :                                 appendStringInfoChar(&result, *sp);
      74                 :           0 :                         }
      75         [ #  # ]:           0 :                         else if (sp[1] == '\0')
      76                 :             :                         {
      77                 :             :                                 /* Incomplete escape sequence, expected a character afterward */
      78                 :             : #ifdef FRONTEND
      79                 :           0 :                                 pg_log_error("invalid value for parameter \"%s\": \"%s\"", param_name, instr);
      80                 :           0 :                                 pg_log_error_detail("String ends unexpectedly after escape character \"%%\".");
      81                 :           0 :                                 exit(1);
      82                 :             : #else
      83   [ #  #  #  # ]:           0 :                                 ereport(ERROR,
      84                 :             :                                                 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
      85                 :             :                                                 errmsg("invalid value for parameter \"%s\": \"%s\"", param_name, instr),
      86                 :             :                                                 errdetail("String ends unexpectedly after escape character \"%%\"."));
      87                 :             : #endif
      88                 :           0 :                         }
      89                 :             :                         else
      90                 :             :                         {
      91                 :             :                                 /* Look up placeholder character */
      92                 :           0 :                                 bool            found = false;
      93                 :           0 :                                 va_list         ap;
      94                 :             : 
      95                 :           0 :                                 sp++;
      96                 :             : 
      97                 :           0 :                                 va_start(ap, letters);
      98         [ #  # ]:           0 :                                 for (const char *lp = letters; *lp; lp++)
      99                 :             :                                 {
     100                 :           0 :                                         char       *val = va_arg(ap, char *);
     101                 :             : 
     102         [ #  # ]:           0 :                                         if (*sp == *lp)
     103                 :             :                                         {
     104         [ #  # ]:           0 :                                                 if (val)
     105                 :             :                                                 {
     106                 :           0 :                                                         appendStringInfoString(&result, val);
     107                 :           0 :                                                         found = true;
     108                 :           0 :                                                 }
     109                 :             :                                                 /* If val is NULL, we will report an error. */
     110                 :           0 :                                                 break;
     111                 :             :                                         }
     112         [ #  # ]:           0 :                                 }
     113                 :           0 :                                 va_end(ap);
     114         [ #  # ]:           0 :                                 if (!found)
     115                 :             :                                 {
     116                 :             :                                         /* Unknown placeholder */
     117                 :             : #ifdef FRONTEND
     118                 :           0 :                                         pg_log_error("invalid value for parameter \"%s\": \"%s\"", param_name, instr);
     119                 :           0 :                                         pg_log_error_detail("String contains unexpected placeholder \"%%%c\".", *sp);
     120                 :           0 :                                         exit(1);
     121                 :             : #else
     122   [ #  #  #  # ]:           0 :                                         ereport(ERROR,
     123                 :             :                                                         errcode(ERRCODE_INVALID_PARAMETER_VALUE),
     124                 :             :                                                         errmsg("invalid value for parameter \"%s\": \"%s\"", param_name, instr),
     125                 :             :                                                         errdetail("String contains unexpected placeholder \"%%%c\".", *sp));
     126                 :             : #endif
     127                 :           0 :                                 }
     128                 :           0 :                         }
     129                 :           0 :                 }
     130                 :             :                 else
     131                 :             :                 {
     132                 :           0 :                         appendStringInfoChar(&result, *sp);
     133                 :             :                 }
     134                 :           0 :         }
     135                 :             : 
     136                 :           0 :         return result.data;
     137                 :           0 : }
        

Generated by: LCOV version 2.3.2-1