* Attach substitute and/or assign hook functions to the named variable. * If you need only one hook, pass NULL for the other. * * If the variable doesn't already exist, create it with value NULL, just so * we have a place to store the hook function(s). (The substitute hook might * immediately change the NULL to something else; if not, this state is * externally the same as the variable not
| 312 | * because this should get called before any user-supplied value is assigned. |
| 313 | */ |
| 314 | void |
| 315 | SetVariableHooks(VariableSpace space, const char *name, |
| 316 | VariableSubstituteHook shook, |
| 317 | VariableAssignHook ahook) |
| 318 | { |
| 319 | struct _variable *current, |
| 320 | *previous; |
| 321 | |
| 322 | if (!space || !name) |
| 323 | return; |
| 324 | |
| 325 | if (!valid_variable_name(name)) |
| 326 | return; |
| 327 | |
| 328 | for (previous = space, current = space->next; |
| 329 | current; |
| 330 | previous = current, current = current->next) |
| 331 | { |
| 332 | int cmp = strcmp(current->name, name); |
| 333 | |
| 334 | if (cmp == 0) |
| 335 | { |
| 336 | /* found entry, so update */ |
| 337 | current->substitute_hook = shook; |
| 338 | current->assign_hook = ahook; |
| 339 | if (shook) |
| 340 | current->value = (*shook) (current->value); |
| 341 | if (ahook) |
| 342 | (void) (*ahook) (current->value); |
| 343 | return; |
| 344 | } |
| 345 | if (cmp > 0) |
| 346 | break; /* it's not there */ |
| 347 | } |
| 348 | |
| 349 | /* not present, make new entry */ |
| 350 | current = pg_malloc(sizeof *current); |
| 351 | current->name = pg_strdup(name); |
| 352 | current->value = NULL; |
| 353 | current->substitute_hook = shook; |
| 354 | current->assign_hook = ahook; |
| 355 | current->next = previous->next; |
| 356 | previous->next = current; |
| 357 | if (shook) |
| 358 | current->value = (*shook) (current->value); |
| 359 | if (ahook) |
| 360 | (void) (*ahook) (current->value); |
| 361 | } |
| 362 | |
| 363 | /* |
| 364 | * Return true iff the named variable has substitute and/or assign hook |
no test coverage detected