LCOV - differential code coverage report
Current view: top level - src/common - percentrepl.c (source / functions) Coverage Total Hit UNC GNC
Current: Differential Code Coverage HEAD vs 15 Lines: 66.7 % 30 20 10 20
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 1 1 1
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (60,120] days: 66.7 % 30 20 10 20
Legend: Lines: hit not hit Function coverage date bins:
(60,120] days: 100.0 % 1 1 1

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * percentrepl.c
                                  4                 :  *    Common routines to replace percent placeholders in strings
                                  5                 :  *
                                  6                 :  * Portions Copyright (c) 1996-2023, 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 *
   88 peter                      59 GNC         165 : replace_percent_placeholders(const char *instr, const char *param_name, const char *letters,...)
                                 60                 : {
                                 61                 :     StringInfoData result;
                                 62                 : 
                                 63             165 :     initStringInfo(&result);
                                 64                 : 
                                 65           16917 :     for (const char *sp = instr; *sp; sp++)
                                 66                 :     {
                                 67           16752 :         if (*sp == '%')
                                 68                 :         {
                                 69             316 :             if (sp[1] == '%')
                                 70                 :             {
                                 71                 :                 /* Convert %% to a single % */
   88 peter                      72 UNC           0 :                 sp++;
                                 73               0 :                 appendStringInfoChar(&result, *sp);
                                 74                 :             }
   88 peter                      75 GNC         316 :             else if (sp[1] == '\0')
                                 76                 :             {
                                 77                 :                 /* Incomplete escape sequence, expected a character afterward */
                                 78                 : #ifdef FRONTEND
   88 peter                      79 UNC           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                 :             }
                                 89                 :             else
                                 90                 :             {
                                 91                 :                 /* Look up placeholder character */
   88 peter                      92 GNC         316 :                 bool        found = false;
                                 93                 :                 va_list     ap;
                                 94                 : 
                                 95             316 :                 sp++;
                                 96                 : 
                                 97             316 :                 va_start(ap, letters);
                                 98             607 :                 for (const char *lp = letters; *lp; lp++)
                                 99                 :                 {
                                100             607 :                     char       *val = va_arg(ap, char *);
                                101                 : 
                                102             607 :                     if (*sp == *lp)
                                103                 :                     {
                                104             316 :                         if (val)
                                105                 :                         {
                                106             316 :                             appendStringInfoString(&result, val);
                                107             316 :                             found = true;
                                108                 :                         }
                                109                 :                         /* If val is NULL, we will report an error. */
                                110             316 :                         break;
                                111                 :                     }
                                112                 :                 }
                                113             316 :                 va_end(ap);
                                114             316 :                 if (!found)
                                115                 :                 {
                                116                 :                     /* Unknown escape sequence */
                                117                 : #ifdef FRONTEND
   88 peter                     118 UNC           0 :                     pg_log_error("invalid value for parameter \"%s\": \"%s\"", param_name, instr);
                                119               0 :                     pg_log_error_detail("String contains unexpected escape sequence \"%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 escape sequence \"%c\".", *sp));
                                126                 : #endif
                                127                 :                 }
                                128                 :             }
                                129                 :         }
                                130                 :         else
                                131                 :         {
   88 peter                     132 GNC       16436 :             appendStringInfoChar(&result, *sp);
                                133                 :         }
                                134                 :     }
                                135                 : 
                                136             165 :     return result.data;
                                137                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a