chooks.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /* Copyright 1995-1996,1998-2001,2003,2006,2008-2009,2011,2018
  2. Free Software Foundation, Inc.
  3. This file is part of Guile.
  4. Guile is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Lesser General Public License as published
  6. by the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. Guile is distributed in the hope that it will be useful, but WITHOUT
  9. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  11. License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with Guile. If not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #ifdef HAVE_CONFIG_H
  16. # include <config.h>
  17. #endif
  18. #include <stdio.h>
  19. #include "gc.h"
  20. #include "chooks.h"
  21. /* C level hooks
  22. *
  23. */
  24. /* Hint for `scm_gc_malloc ()' and friends. */
  25. static const char hook_entry_gc_hint[] = "hook entry";
  26. void
  27. scm_c_hook_init (scm_t_c_hook *hook, void *hook_data, scm_t_c_hook_type type)
  28. {
  29. hook->first = 0;
  30. hook->type = type;
  31. hook->data = hook_data;
  32. }
  33. void
  34. scm_c_hook_add (scm_t_c_hook *hook,
  35. scm_t_c_hook_function func,
  36. void *fn_data,
  37. int appendp)
  38. {
  39. scm_t_c_hook_entry *entry;
  40. scm_t_c_hook_entry **loc = &hook->first;
  41. entry = scm_gc_malloc (sizeof (scm_t_c_hook_entry), hook_entry_gc_hint);
  42. if (appendp)
  43. while (*loc)
  44. loc = &(*loc)->next;
  45. entry->next = *loc;
  46. entry->func = func;
  47. entry->data = fn_data;
  48. *loc = entry;
  49. }
  50. void
  51. scm_c_hook_remove (scm_t_c_hook *hook,
  52. scm_t_c_hook_function func,
  53. void *fn_data)
  54. {
  55. scm_t_c_hook_entry **loc = &hook->first;
  56. while (*loc)
  57. {
  58. if ((*loc)->func == func && (*loc)->data == fn_data)
  59. {
  60. *loc = (*loc)->next;
  61. return;
  62. }
  63. loc = &(*loc)->next;
  64. }
  65. fprintf (stderr, "Attempt to remove non-existent hook function\n");
  66. abort ();
  67. }
  68. void *
  69. scm_c_hook_run (scm_t_c_hook *hook, void *data)
  70. {
  71. scm_t_c_hook_entry *entry = hook->first;
  72. scm_t_c_hook_type type = hook->type;
  73. void *res = 0;
  74. while (entry)
  75. {
  76. res = (entry->func) (hook->data, entry->data, data);
  77. if (res)
  78. {
  79. if (type == SCM_C_HOOK_OR)
  80. break;
  81. }
  82. else
  83. {
  84. if (type == SCM_C_HOOK_AND)
  85. break;
  86. }
  87. entry = entry->next;
  88. }
  89. return res;
  90. }