LCOV - differential code coverage report
Current view: top level - src/bin/psql - variables.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: 380a8b2ea024c33a35e7abc8628e7c4f52f9f9f9 vs db5ed03217b9c238703df8b4b286115d6e940488 Lines: 80.3 % 188 151 37 3 148 3
Current Date: 2026-05-29 21:51:00 -0400 Functions: 84.6 % 13 11 2 3 8
Baseline: lcov-20260530-034037-baseline Branches: 63.8 % 160 102 58 102
Baseline Date: 2026-05-29 14:39:03 -0700 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 0.0 % 1 0 1
(30,360] days: 50.0 % 8 4 4 3 1
(360..) days: 82.1 % 179 147 32 147
Function coverage date bins:
(360..) days: 84.6 % 13 11 2 3 8
Branch coverage date bins:
(360..) days: 63.8 % 160 102 58 102

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  * psql - the PostgreSQL interactive terminal
                                  3                 :                :  *
                                  4                 :                :  * Copyright (c) 2000-2026, PostgreSQL Global Development Group
                                  5                 :                :  *
                                  6                 :                :  * src/bin/psql/variables.c
                                  7                 :                :  */
                                  8                 :                : #include "postgres_fe.h"
                                  9                 :                : 
                                 10                 :                : #include <math.h>
                                 11                 :                : 
                                 12                 :                : #include "common.h"
                                 13                 :                : #include "common/logging.h"
                                 14                 :                : #include "variables.h"
                                 15                 :                : 
                                 16                 :                : /*
                                 17                 :                :  * Check whether a variable's name is allowed.
                                 18                 :                :  *
                                 19                 :                :  * We allow any non-ASCII character, as well as ASCII letters, digits, and
                                 20                 :                :  * underscore.  Keep this in sync with the definition of variable_char in
                                 21                 :                :  * psqlscan.l and psqlscanslash.l.
                                 22                 :                :  */
                                 23                 :                : static bool
 5391 tgl@sss.pgh.pa.us          24                 :CBC     2212252 : valid_variable_name(const char *name)
                                 25                 :                : {
                                 26                 :        2212252 :     const unsigned char *ptr = (const unsigned char *) name;
                                 27                 :                : 
                                 28                 :                :     /* Mustn't be zero-length */
                                 29         [ -  + ]:        2212252 :     if (*ptr == '\0')
 5391 tgl@sss.pgh.pa.us          30                 :UBC           0 :         return false;
                                 31                 :                : 
 5391 tgl@sss.pgh.pa.us          32         [ +  + ]:CBC    31157997 :     while (*ptr)
                                 33                 :                :     {
                                 34         [ +  - ]:       28945753 :         if (IS_HIGHBIT_SET(*ptr) ||
                                 35                 :       28945753 :             strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
                                 36         [ +  + ]:       28945753 :                    "_0123456789", *ptr) != NULL)
                                 37                 :       28945745 :             ptr++;
                                 38                 :                :         else
                                 39                 :              8 :             return false;
                                 40                 :                :     }
                                 41                 :                : 
                                 42                 :        2212244 :     return true;
                                 43                 :                : }
                                 44                 :                : 
                                 45                 :                : /*
                                 46                 :                :  * A "variable space" is represented by an otherwise-unused struct _variable
                                 47                 :                :  * that serves as list header.
                                 48                 :                :  *
                                 49                 :                :  * The list entries are kept in name order (according to strcmp).  This
                                 50                 :                :  * is mainly to make the output of PrintVariables() more pleasing.
                                 51                 :                :  */
                                 52                 :                : VariableSpace
 9704 bruce@momjian.us           53                 :          10797 : CreateVariableSpace(void)
                                 54                 :                : {
                                 55                 :                :     struct _variable *ptr;
                                 56                 :                : 
   92 michael@paquier.xyz        57                 :GNC       10797 :     ptr = pg_malloc_object(struct _variable);
 7214 tgl@sss.pgh.pa.us          58                 :CBC       10797 :     ptr->name = NULL;
                                 59                 :          10797 :     ptr->value = NULL;
 3405                            60                 :          10797 :     ptr->substitute_hook = NULL;
 7214                            61                 :          10797 :     ptr->assign_hook = NULL;
                                 62                 :          10797 :     ptr->next = NULL;
                                 63                 :                : 
 9704 bruce@momjian.us           64                 :          10797 :     return ptr;
                                 65                 :                : }
                                 66                 :                : 
                                 67                 :                : /*
                                 68                 :                :  * Get string value of variable, or NULL if it's not defined.
                                 69                 :                :  *
                                 70                 :                :  * Note: result is valid until variable is next assigned to.
                                 71                 :                :  */
                                 72                 :                : const char *
                                 73                 :           2754 : GetVariable(VariableSpace space, const char *name)
                                 74                 :                : {
                                 75                 :                :     struct _variable *current;
                                 76                 :                : 
                                 77         [ -  + ]:           2754 :     if (!space)
 9704 bruce@momjian.us           78                 :UBC           0 :         return NULL;
                                 79                 :                : 
 7283 tgl@sss.pgh.pa.us          80         [ +  + ]:CBC      106648 :     for (current = space->next; current; current = current->next)
                                 81                 :                :     {
 3405                            82                 :         106647 :         int         cmp = strcmp(current->name, name);
                                 83                 :                : 
                                 84         [ +  + ]:         106647 :         if (cmp == 0)
                                 85                 :                :         {
                                 86                 :                :             /* this is correct answer when value is NULL, too */
 9704 bruce@momjian.us           87                 :           2421 :             return current->value;
                                 88                 :                :         }
 3405 tgl@sss.pgh.pa.us          89         [ +  + ]:         104226 :         if (cmp > 0)
                                 90                 :            332 :             break;              /* it's not there */
                                 91                 :                :     }
                                 92                 :                : 
 9704 bruce@momjian.us           93                 :            333 :     return NULL;
                                 94                 :                : }
                                 95                 :                : 
                                 96                 :                : /*
                                 97                 :                :  * Try to interpret "value" as a boolean value, and if successful,
                                 98                 :                :  * store it in *result.  Otherwise don't clobber *result.
                                 99                 :                :  *
                                100                 :                :  * Valid values are: true, false, yes, no, on, off, 1, 0; as well as unique
                                101                 :                :  * prefixes thereof.
                                102                 :                :  *
                                103                 :                :  * "name" is the name of the variable we're assigning to, to use in error
                                104                 :                :  * report if any.  Pass name == NULL to suppress the error report.
                                105                 :                :  *
                                106                 :                :  * Return true when "value" is syntactically valid, false otherwise.
                                107                 :                :  */
                                108                 :                : bool
 3407 tgl@sss.pgh.pa.us         109                 :         149451 : ParseVariableBool(const char *value, const char *name, bool *result)
                                110                 :                : {
                                111                 :                :     size_t      len;
                                112                 :         149451 :     bool        valid = true;
                                113                 :                : 
                                114                 :                :     /* Treat "unset" as an empty string, which will lead to error below */
 6597 bruce@momjian.us          115         [ -  + ]:         149451 :     if (value == NULL)
 3405 tgl@sss.pgh.pa.us         116                 :UBC           0 :         value = "";
                                117                 :                : 
 6597 bruce@momjian.us          118                 :CBC      149451 :     len = strlen(value);
                                119                 :                : 
 3407 tgl@sss.pgh.pa.us         120   [ +  -  +  + ]:         149451 :     if (len > 0 && pg_strncasecmp(value, "true", len) == 0)
                                121                 :            162 :         *result = true;
                                122   [ +  -  +  + ]:         149289 :     else if (len > 0 && pg_strncasecmp(value, "false", len) == 0)
                                123                 :            210 :         *result = false;
                                124   [ +  -  +  + ]:         149079 :     else if (len > 0 && pg_strncasecmp(value, "yes", len) == 0)
                                125                 :              4 :         *result = true;
                                126   [ +  -  +  + ]:         149075 :     else if (len > 0 && pg_strncasecmp(value, "no", len) == 0)
                                127                 :              4 :         *result = false;
                                128                 :                :     /* 'o' is not unique enough */
 6597 bruce@momjian.us          129         [ +  + ]:         149071 :     else if (pg_strncasecmp(value, "on", (len > 2 ? len : 2)) == 0)
 3407 tgl@sss.pgh.pa.us         130                 :          33777 :         *result = true;
 6597 bruce@momjian.us          131         [ +  + ]:         115294 :     else if (pg_strncasecmp(value, "off", (len > 2 ? len : 2)) == 0)
 3407 tgl@sss.pgh.pa.us         132                 :         108111 :         *result = false;
 6597 bruce@momjian.us          133         [ +  + ]:           7183 :     else if (pg_strcasecmp(value, "1") == 0)
 3407 tgl@sss.pgh.pa.us         134                 :           7166 :         *result = true;
 6597 bruce@momjian.us          135         [ +  + ]:             17 :     else if (pg_strcasecmp(value, "0") == 0)
 3407 tgl@sss.pgh.pa.us         136                 :              5 :         *result = false;
                                137                 :                :     else
                                138                 :                :     {
                                139                 :                :         /* string is not recognized; don't clobber *result */
 4168                           140         [ +  + ]:             12 :         if (name)
 2616 peter@eisentraut.org      141                 :              8 :             pg_log_error("unrecognized value \"%s\" for \"%s\": Boolean expected",
                                142                 :                :                          value, name);
 3407 tgl@sss.pgh.pa.us         143                 :             12 :         valid = false;
                                144                 :                :     }
                                145                 :         149451 :     return valid;
                                146                 :                : }
                                147                 :                : 
                                148                 :                : /*
                                149                 :                :  * Try to interpret "value" as an integer value, and if successful,
                                150                 :                :  * store it in *result.  Otherwise don't clobber *result.
                                151                 :                :  *
                                152                 :                :  * "name" is the name of the variable we're assigning to, to use in error
                                153                 :                :  * report if any.  Pass name == NULL to suppress the error report.
                                154                 :                :  *
                                155                 :                :  * Return true when "value" is syntactically valid, false otherwise.
                                156                 :                :  */
                                157                 :                : bool
                                158                 :          32444 : ParseVariableNum(const char *value, const char *name, int *result)
                                159                 :                : {
                                160                 :                :     char       *end;
                                161                 :                :     long        numval;
                                162                 :                : 
                                163                 :                :     /* Treat "unset" as an empty string, which will lead to error below */
                                164         [ -  + ]:          32444 :     if (value == NULL)
 3405 tgl@sss.pgh.pa.us         165                 :UBC           0 :         value = "";
                                166                 :                : 
 3407 tgl@sss.pgh.pa.us         167                 :CBC       32444 :     errno = 0;
                                168                 :          32444 :     numval = strtol(value, &end, 0);
                                169   [ +  -  +  +  :          32444 :     if (errno == 0 && *end == '\0' && end != value && numval == (int) numval)
                                        +  -  +  - ]
                                170                 :                :     {
                                171                 :          32440 :         *result = (int) numval;
                                172                 :          32440 :         return true;
                                173                 :                :     }
                                174                 :                :     else
                                175                 :                :     {
                                176                 :                :         /* string is not recognized; don't clobber *result */
                                177         [ +  - ]:              4 :         if (name)
 2616 peter@eisentraut.org      178                 :              4 :             pg_log_error("invalid value \"%s\" for \"%s\": integer expected",
                                179                 :                :                          value, name);
 3407 tgl@sss.pgh.pa.us         180                 :              4 :         return false;
                                181                 :                :     }
                                182                 :                : }
                                183                 :                : 
                                184                 :                : /*
                                185                 :                :  * Try to interpret "value" as a double value, and if successful store it in
                                186                 :                :  * *result. If unsuccessful, *result isn't clobbered. "name" is the variable
                                187                 :                :  * which is being assigned, the value of which is only used to produce a good
                                188                 :                :  * error message. Pass NULL as the name to suppress the error message.  The
                                189                 :                :  * value must be within the range [min,max] in order to be considered valid.
                                190                 :                :  *
                                191                 :                :  * Returns true, with *result containing the interpreted value, if "value" is
                                192                 :                :  * syntactically valid, else false (with *result unchanged).
                                193                 :                :  */
                                194                 :                : bool
  431 dgustafsson@postgres      195                 :          10801 : ParseVariableDouble(const char *value, const char *name, double *result, double min, double max)
                                196                 :                : {
                                197                 :                :     char       *end;
                                198                 :                :     double      dblval;
                                199                 :                : 
                                200                 :                :     /*
                                201                 :                :      * Empty-string input has historically been treated differently by strtod
                                202                 :                :      * on various platforms, so handle that by specifically checking for it.
                                203                 :                :      */
                                204   [ +  -  -  + ]:          10801 :     if ((value == NULL) || (*value == '\0'))
                                205                 :                :     {
  431 dgustafsson@postgres      206         [ #  # ]:UBC           0 :         if (name)
  348 peter@eisentraut.org      207                 :              0 :             pg_log_error("invalid input syntax for variable \"%s\"", name);
  431 dgustafsson@postgres      208                 :              0 :         return false;
                                209                 :                :     }
                                210                 :                : 
  431 dgustafsson@postgres      211                 :CBC       10801 :     errno = 0;
                                212                 :          10801 :     dblval = strtod(value, &end);
                                213   [ +  +  +  -  :          10801 :     if (errno == 0 && *end == '\0' && end != value)
                                              +  - ]
                                214                 :                :     {
                                215         [ -  + ]:          10800 :         if (dblval < min)
                                216                 :                :         {
  431 dgustafsson@postgres      217         [ #  # ]:UBC           0 :             if (name)
  348 peter@eisentraut.org      218                 :              0 :                 pg_log_error("invalid value \"%s\" for variable \"%s\": must be greater than %.2f",
                                219                 :                :                              value, name, min);
  431 dgustafsson@postgres      220                 :              0 :             return false;
                                221                 :                :         }
  431 dgustafsson@postgres      222         [ -  + ]:CBC       10800 :         else if (dblval > max)
                                223                 :                :         {
  431 dgustafsson@postgres      224         [ #  # ]:UBC           0 :             if (name)
  348 peter@eisentraut.org      225                 :              0 :                 pg_log_error("invalid value \"%s\" for variable \"%s\": must be less than %.2f",
                                226                 :                :                              value, name, max);
   12 dgustafsson@postgres      227                 :              0 :             return false;
                                228                 :                :         }
  431 dgustafsson@postgres      229                 :CBC       10800 :         *result = dblval;
                                230                 :          10800 :         return true;
                                231                 :                :     }
                                232                 :                : 
                                233                 :                :     /*
                                234                 :                :      * Cater for platforms which treat values which aren't zero, but that are
                                235                 :                :      * too close to zero to have full precision, by checking for zero or real
                                236                 :                :      * out-of-range values.
                                237                 :                :      */
  429                           238   [ +  -  +  - ]:              1 :     else if ((errno == ERANGE) &&
  431                           239   [ -  +  -  - ]:              1 :              (dblval == 0.0 || dblval >= HUGE_VAL || dblval <= -HUGE_VAL))
                                240                 :                :     {
                                241         [ +  - ]:              1 :         if (name)
  348 peter@eisentraut.org      242                 :              1 :             pg_log_error("value \"%s\" is out of range for variable \"%s\"", value, name);
  431 dgustafsson@postgres      243                 :              1 :         return false;
                                244                 :                :     }
                                245                 :                :     else
                                246                 :                :     {
  431 dgustafsson@postgres      247         [ #  # ]:UBC           0 :         if (name)
  348 peter@eisentraut.org      248                 :              0 :             pg_log_error("invalid value \"%s\" for variable \"%s\"", value, name);
  431 dgustafsson@postgres      249                 :              0 :         return false;
                                250                 :                :     }
                                251                 :                : }
                                252                 :                : 
                                253                 :                : /*
                                254                 :                :  * Print values of all variables.
                                255                 :                :  */
                                256                 :                : void
 8472 bruce@momjian.us          257                 :              0 : PrintVariables(VariableSpace space)
                                258                 :                : {
                                259                 :                :     struct _variable *ptr;
                                260                 :                : 
 7283 tgl@sss.pgh.pa.us         261         [ #  # ]:              0 :     if (!space)
                                262                 :              0 :         return;
                                263                 :                : 
 8335 bruce@momjian.us          264         [ #  # ]:              0 :     for (ptr = space->next; ptr; ptr = ptr->next)
                                265                 :                :     {
 7214 tgl@sss.pgh.pa.us         266         [ #  # ]:              0 :         if (ptr->value)
                                267                 :              0 :             printf("%s = '%s'\n", ptr->name, ptr->value);
 7290                           268         [ #  # ]:              0 :         if (cancel_pressed)
                                269                 :              0 :             break;
                                270                 :                :     }
                                271                 :                : }
                                272                 :                : 
                                273                 :                : /*
                                274                 :                :  * Set the variable named "name" to value "value",
                                275                 :                :  * or delete it if "value" is NULL.
                                276                 :                :  *
                                277                 :                :  * Returns true if successful, false if not; in the latter case a suitable
                                278                 :                :  * error message has been printed, except for the unexpected case of
                                279                 :                :  * space or name being NULL.
                                280                 :                :  */
                                281                 :                : bool
 9704 bruce@momjian.us          282                 :CBC     1963921 : SetVariable(VariableSpace space, const char *name, const char *value)
                                283                 :                : {
                                284                 :                :     struct _variable *current,
                                285                 :                :                *previous;
                                286                 :                : 
 3407 tgl@sss.pgh.pa.us         287   [ +  -  -  + ]:        1963921 :     if (!space || !name)
 9704 bruce@momjian.us          288                 :UBC           0 :         return false;
                                289                 :                : 
 5391 tgl@sss.pgh.pa.us         290         [ +  + ]:CBC     1963921 :     if (!valid_variable_name(name))
                                291                 :                :     {
                                292                 :                :         /* Deletion of non-existent variable is not an error */
 3405                           293         [ -  + ]:              8 :         if (!value)
 3405 tgl@sss.pgh.pa.us         294                 :UBC           0 :             return true;
 2616 peter@eisentraut.org      295                 :CBC           8 :         pg_log_error("invalid variable name: \"%s\"", name);
 9704 bruce@momjian.us          296                 :              8 :         return false;
                                297                 :                :     }
                                298                 :                : 
 7283 tgl@sss.pgh.pa.us         299                 :        1963913 :     for (previous = space, current = space->next;
                                300         [ +  + ]:       42563538 :          current;
                                301                 :       40599625 :          previous = current, current = current->next)
                                302                 :                :     {
 3405                           303                 :       42563047 :         int         cmp = strcmp(current->name, name);
                                304                 :                : 
                                305         [ +  + ]:       42563047 :         if (cmp == 0)
                                306                 :                :         {
                                307                 :                :             /*
                                308                 :                :              * Found entry, so update, unless assign hook returns false.
                                309                 :                :              *
                                310                 :                :              * We must duplicate the passed value to start with.  This
                                311                 :                :              * simplifies the API for substitute hooks.  Moreover, some assign
                                312                 :                :              * hooks assume that the passed value has the same lifespan as the
                                313                 :                :              * variable.  Having to free the string again on failure is a
                                314                 :                :              * small price to pay for keeping these APIs simple.
                                315                 :                :              */
                                316         [ +  + ]:        1746220 :             char       *new_value = value ? pg_strdup(value) : NULL;
                                317                 :                :             bool        confirmed;
                                318                 :                : 
                                319         [ +  + ]:        1746220 :             if (current->substitute_hook)
 3187 peter_e@gmx.net           320                 :          42511 :                 new_value = current->substitute_hook(new_value);
                                321                 :                : 
 7214 tgl@sss.pgh.pa.us         322         [ +  + ]:        1746220 :             if (current->assign_hook)
 3187 peter_e@gmx.net           323                 :          74902 :                 confirmed = current->assign_hook(new_value);
                                324                 :                :             else
 3407 tgl@sss.pgh.pa.us         325                 :        1671318 :                 confirmed = true;
                                326                 :                : 
                                327         [ +  + ]:        1746220 :             if (confirmed)
                                328                 :                :             {
 1443 peter@eisentraut.org      329                 :        1746207 :                 pg_free(current->value);
 3407 tgl@sss.pgh.pa.us         330                 :        1746207 :                 current->value = new_value;
                                331                 :                : 
                                332                 :                :                 /*
                                333                 :                :                  * If we deleted the value, and there are no hooks to
                                334                 :                :                  * remember, we can discard the variable altogether.
                                335                 :                :                  */
 3405                           336         [ +  + ]:        1746207 :                 if (new_value == NULL &&
                                337         [ +  - ]:              4 :                     current->substitute_hook == NULL &&
                                338         [ +  - ]:              4 :                     current->assign_hook == NULL)
                                339                 :                :                 {
                                340                 :              4 :                     previous->next = current->next;
                                341                 :              4 :                     free(current->name);
                                342                 :              4 :                     free(current);
                                343                 :                :                 }
                                344                 :                :             }
                                345                 :                :             else
 3265                           346                 :             13 :                 pg_free(new_value); /* current->value is left unchanged */
                                347                 :                : 
 3407                           348                 :        1746220 :             return confirmed;
                                349                 :                :         }
 3405                           350         [ +  + ]:       40816827 :         if (cmp > 0)
                                351                 :         217202 :             break;              /* it's not there */
                                352                 :                :     }
                                353                 :                : 
                                354                 :                :     /* not present, make new entry ... unless we were asked to delete */
                                355         [ +  + ]:         217693 :     if (value)
                                356                 :                :     {
   92 michael@paquier.xyz       357                 :GNC      196331 :         current = pg_malloc_object(struct _variable);
 3405 tgl@sss.pgh.pa.us         358                 :CBC      196331 :         current->name = pg_strdup(name);
                                359                 :         196331 :         current->value = pg_strdup(value);
                                360                 :         196331 :         current->substitute_hook = NULL;
                                361                 :         196331 :         current->assign_hook = NULL;
                                362                 :         196331 :         current->next = previous->next;
                                363                 :         196331 :         previous->next = current;
                                364                 :                :     }
 7214                           365                 :         217693 :     return true;
                                366                 :                : }
                                367                 :                : 
                                368                 :                : /*
                                369                 :                :  * Attach substitute and/or assign hook functions to the named variable.
                                370                 :                :  * If you need only one hook, pass NULL for the other.
                                371                 :                :  *
                                372                 :                :  * If the variable doesn't already exist, create it with value NULL, just so
                                373                 :                :  * we have a place to store the hook function(s).  (The substitute hook might
                                374                 :                :  * immediately change the NULL to something else; if not, this state is
                                375                 :                :  * externally the same as the variable not being defined.)
                                376                 :                :  *
                                377                 :                :  * The substitute hook, if given, is immediately called on the variable's
                                378                 :                :  * value.  Then the assign hook, if given, is called on the variable's value.
                                379                 :                :  * This is meant to let it update any derived psql state.  If the assign hook
                                380                 :                :  * doesn't like the current value, it will print a message to that effect,
                                381                 :                :  * but we'll ignore it.  Generally we do not expect any such failure here,
                                382                 :                :  * because this should get called before any user-supplied value is assigned.
                                383                 :                :  */
                                384                 :                : void
 3405                           385                 :         248331 : SetVariableHooks(VariableSpace space, const char *name,
                                386                 :                :                  VariableSubstituteHook shook,
                                387                 :                :                  VariableAssignHook ahook)
                                388                 :                : {
                                389                 :                :     struct _variable *current,
                                390                 :                :                *previous;
                                391                 :                : 
 3407                           392   [ +  -  -  + ]:         248331 :     if (!space || !name)
 3407 tgl@sss.pgh.pa.us         393                 :UBC           0 :         return;
                                394                 :                : 
 5391 tgl@sss.pgh.pa.us         395         [ -  + ]:CBC      248331 :     if (!valid_variable_name(name))
 3407 tgl@sss.pgh.pa.us         396                 :UBC           0 :         return;
                                397                 :                : 
 7214 tgl@sss.pgh.pa.us         398                 :CBC      248331 :     for (previous = space, current = space->next;
                                399         [ +  + ]:        1889475 :          current;
                                400                 :        1641144 :          previous = current, current = current->next)
                                401                 :                :     {
 3405                           402                 :        1813896 :         int         cmp = strcmp(current->name, name);
                                403                 :                : 
                                404         [ -  + ]:        1813896 :         if (cmp == 0)
                                405                 :                :         {
                                406                 :                :             /* found entry, so update */
 3405 tgl@sss.pgh.pa.us         407                 :UBC           0 :             current->substitute_hook = shook;
                                408                 :              0 :             current->assign_hook = ahook;
                                409         [ #  # ]:              0 :             if (shook)
                                410                 :              0 :                 current->value = (*shook) (current->value);
                                411         [ #  # ]:              0 :             if (ahook)
                                412                 :              0 :                 (void) (*ahook) (current->value);
 3407                           413                 :              0 :             return;
                                414                 :                :         }
 3405 tgl@sss.pgh.pa.us         415         [ +  + ]:CBC     1813896 :         if (cmp > 0)
                                416                 :         172752 :             break;              /* it's not there */
                                417                 :                :     }
                                418                 :                : 
                                419                 :                :     /* not present, make new entry */
   92 michael@paquier.xyz       420                 :GNC      248331 :     current = pg_malloc_object(struct _variable);
 7214 tgl@sss.pgh.pa.us         421                 :CBC      248331 :     current->name = pg_strdup(name);
                                422                 :         248331 :     current->value = NULL;
 3405                           423                 :         248331 :     current->substitute_hook = shook;
                                424                 :         248331 :     current->assign_hook = ahook;
                                425                 :         248331 :     current->next = previous->next;
 7214                           426                 :         248331 :     previous->next = current;
 3405                           427         [ +  + ]:         248331 :     if (shook)
                                428                 :         205143 :         current->value = (*shook) (current->value);
                                429         [ +  - ]:         248331 :     if (ahook)
                                430                 :         248331 :         (void) (*ahook) (current->value);
                                431                 :                : }
                                432                 :                : 
                                433                 :                : /*
                                434                 :                :  * Return true iff the named variable has substitute and/or assign hook
                                435                 :                :  * functions.
                                436                 :                :  */
                                437                 :                : bool
 2028 noah@leadboat.com         438                 :            660 : VariableHasHook(VariableSpace space, const char *name)
                                439                 :                : {
                                440                 :                :     struct _variable *current;
                                441                 :                : 
                                442         [ -  + ]:            660 :     Assert(space);
                                443         [ -  + ]:            660 :     Assert(name);
                                444                 :                : 
                                445         [ +  + ]:          32839 :     for (current = space->next; current; current = current->next)
                                446                 :                :     {
                                447                 :          32601 :         int         cmp = strcmp(current->name, name);
                                448                 :                : 
                                449         [ +  + ]:          32601 :         if (cmp == 0)
                                450         [ +  + ]:            196 :             return (current->substitute_hook != NULL ||
                                451         [ -  + ]:             96 :                     current->assign_hook != NULL);
                                452         [ +  + ]:          32501 :         if (cmp > 0)
                                453                 :            322 :             break;              /* it's not there */
                                454                 :                :     }
                                455                 :                : 
                                456                 :            560 :     return false;
                                457                 :                : }
                                458                 :                : 
                                459                 :                : /*
                                460                 :                :  * Convenience function to set a variable's value to "on".
                                461                 :                :  */
                                462                 :                : bool
 9603 peter_e@gmx.net           463                 :          30991 : SetVariableBool(VariableSpace space, const char *name)
                                464                 :                : {
 8372 tgl@sss.pgh.pa.us         465                 :          30991 :     return SetVariable(space, name, "on");
                                466                 :                : }
                                467                 :                : 
                                468                 :                : /*
                                469                 :                :  * Attempt to delete variable.
                                470                 :                :  *
                                471                 :                :  * If unsuccessful, print a message and return "false".
                                472                 :                :  * Deleting a nonexistent variable is not an error.
                                473                 :                :  */
                                474                 :                : bool
 9704 bruce@momjian.us          475                 :UBC           0 : DeleteVariable(VariableSpace space, const char *name)
                                476                 :                : {
 3405 tgl@sss.pgh.pa.us         477                 :              0 :     return SetVariable(space, name, NULL);
                                478                 :                : }
                                479                 :                : 
                                480                 :                : /*
                                481                 :                :  * Emit error with suggestions for variables or commands
                                482                 :                :  * accepting enum-style arguments.
                                483                 :                :  * This function just exists to standardize the wording.
                                484                 :                :  * suggestions should follow the format "fee, fi, fo, fum".
                                485                 :                :  */
                                486                 :                : void
 3407 tgl@sss.pgh.pa.us         487                 :CBC           4 : PsqlVarEnumError(const char *name, const char *value, const char *suggestions)
                                488                 :                : {
 2616 peter@eisentraut.org      489                 :              4 :     pg_log_error("unrecognized value \"%s\" for \"%s\"\n"
                                490                 :                :                  "Available values are: %s.",
                                491                 :                :                  value, name, suggestions);
 3407 tgl@sss.pgh.pa.us         492                 :              4 : }
        

Generated by: LCOV version 2.5.0-beta