| 1 | /* |
| 2 | * psql - the PostgreSQL interactive terminal |
| 3 | * |
| 4 | * Copyright (c) 2000-2019, PostgreSQL Global Development Group |
| 5 | * |
| 6 | * This implements a sort of variable repository. One could also think of it |
| 7 | * as a cheap version of an associative array. Each variable has a string |
| 8 | * name and a string value. The value can't be NULL, or more precisely |
| 9 | * that's not distinguishable from the variable being unset. |
| 10 | * |
| 11 | * src/bin/psql/variables.h |
| 12 | */ |
| 13 | #ifndef VARIABLES_H |
| 14 | #define VARIABLES_H |
| 15 | |
| 16 | /* |
| 17 | * Variables can be given "assign hook" functions. The assign hook can |
| 18 | * prevent invalid values from being assigned, and can update internal C |
| 19 | * variables to keep them in sync with the variable's current value. |
| 20 | * |
| 21 | * An assign hook function is called before any attempted assignment, with the |
| 22 | * proposed new value of the variable (or with NULL, if an \unset is being |
| 23 | * attempted). If it returns false, the assignment doesn't occur --- it |
| 24 | * should print an error message with pg_log_error() to tell the user why. |
| 25 | * |
| 26 | * When an assign hook function is installed with SetVariableHooks(), it is |
| 27 | * called with the variable's current value (or with NULL, if it wasn't set |
| 28 | * yet). But its return value is ignored in this case. The hook should be |
| 29 | * set before any possibly-invalid value can be assigned. |
| 30 | */ |
| 31 | typedef bool (*VariableAssignHook) (const char *newval); |
| 32 | |
| 33 | /* |
| 34 | * Variables can also be given "substitute hook" functions. The substitute |
| 35 | * hook can replace values (including NULL) with other values, allowing |
| 36 | * normalization of variable contents. For example, for a boolean variable, |
| 37 | * we wish to interpret "\unset FOO" as "\set FOO off", and we can do that |
| 38 | * by installing a substitute hook. (We can use the same substitute hook |
| 39 | * for all bool or nearly-bool variables, which is why this responsibility |
| 40 | * isn't part of the assign hook.) |
| 41 | * |
| 42 | * The substitute hook is called before any attempted assignment, and before |
| 43 | * the assign hook if any, passing the proposed new value of the variable as a |
| 44 | * malloc'd string (or NULL, if an \unset is being attempted). It can return |
| 45 | * the same value, or a different malloc'd string, or modify the string |
| 46 | * in-place. It should free the passed-in value if it's not returning it. |
| 47 | * The substitute hook generally should not complain about erroneous values; |
| 48 | * that's a job for the assign hook. |
| 49 | * |
| 50 | * When a substitute hook is installed with SetVariableHooks(), it is applied |
| 51 | * to the variable's current value (typically NULL, if it wasn't set yet). |
| 52 | * That also happens before applying the assign hook. |
| 53 | */ |
| 54 | typedef char *(*VariableSubstituteHook) (char *newval); |
| 55 | |
| 56 | /* |
| 57 | * Data structure representing one variable. |
| 58 | * |
| 59 | * Note: if value == NULL then the variable is logically unset, but we are |
| 60 | * keeping the struct around so as not to forget about its hook function(s). |
| 61 | */ |
| 62 | struct _variable |
| 63 | { |
| 64 | char *name; |
| 65 | char *value; |
| 66 | VariableSubstituteHook substitute_hook; |
| 67 | VariableAssignHook assign_hook; |
| 68 | struct _variable *next; |
| 69 | }; |
| 70 | |
| 71 | /* Data structure representing a set of variables */ |
| 72 | typedef struct _variable *VariableSpace; |
| 73 | |
| 74 | |
| 75 | VariableSpace CreateVariableSpace(void); |
| 76 | const char *GetVariable(VariableSpace space, const char *name); |
| 77 | |
| 78 | bool ParseVariableBool(const char *value, const char *name, |
| 79 | bool *result); |
| 80 | |
| 81 | bool ParseVariableNum(const char *value, const char *name, |
| 82 | int *result); |
| 83 | |
| 84 | void PrintVariables(VariableSpace space); |
| 85 | |
| 86 | bool SetVariable(VariableSpace space, const char *name, const char *value); |
| 87 | bool SetVariableBool(VariableSpace space, const char *name); |
| 88 | bool DeleteVariable(VariableSpace space, const char *name); |
| 89 | |
| 90 | void SetVariableHooks(VariableSpace space, const char *name, |
| 91 | VariableSubstituteHook shook, |
| 92 | VariableAssignHook ahook); |
| 93 | |
| 94 | void PsqlVarEnumError(const char *name, const char *value, const char *suggestions); |
| 95 | |
| 96 | #endif /* VARIABLES_H */ |
| 97 | |