* Set the variable named "name" to value "value", * or delete it if "value" is NULL. * * Returns true if successful, false if not; in the latter case a suitable * error message has been printed, except for the unexpected case of * space or name being NULL. */
| 208 | * space or name being NULL. |
| 209 | */ |
| 210 | bool |
| 211 | SetVariable(VariableSpace space, const char *name, const char *value) |
| 212 | { |
| 213 | struct _variable *current, |
| 214 | *previous; |
| 215 | |
| 216 | if (!space || !name) |
| 217 | return false; |
| 218 | |
| 219 | if (!valid_variable_name(name)) |
| 220 | { |
| 221 | /* Deletion of non-existent variable is not an error */ |
| 222 | if (!value) |
| 223 | return true; |
| 224 | pg_log_error("invalid variable name: \"%s\"", name); |
| 225 | return false; |
| 226 | } |
| 227 | |
| 228 | for (previous = space, current = space->next; |
| 229 | current; |
| 230 | previous = current, current = current->next) |
| 231 | { |
| 232 | int cmp = strcmp(current->name, name); |
| 233 | |
| 234 | if (cmp == 0) |
| 235 | { |
| 236 | /* |
| 237 | * Found entry, so update, unless assign hook returns false. |
| 238 | * |
| 239 | * We must duplicate the passed value to start with. This |
| 240 | * simplifies the API for substitute hooks. Moreover, some assign |
| 241 | * hooks assume that the passed value has the same lifespan as the |
| 242 | * variable. Having to free the string again on failure is a |
| 243 | * small price to pay for keeping these APIs simple. |
| 244 | */ |
| 245 | char *new_value = value ? pg_strdup(value) : NULL; |
| 246 | bool confirmed; |
| 247 | |
| 248 | if (current->substitute_hook) |
| 249 | new_value = current->substitute_hook(new_value); |
| 250 | |
| 251 | if (current->assign_hook) |
| 252 | confirmed = current->assign_hook(new_value); |
| 253 | else |
| 254 | confirmed = true; |
| 255 | |
| 256 | if (confirmed) |
| 257 | { |
| 258 | if (current->value) |
| 259 | pg_free(current->value); |
| 260 | current->value = new_value; |
| 261 | |
| 262 | /* |
| 263 | * If we deleted the value, and there are no hooks to |
| 264 | * remember, we can discard the variable altogether. |
| 265 | */ |
| 266 | if (new_value == NULL && |
| 267 | current->substitute_hook == NULL && |
no test coverage detected