handler.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*!
  2. \file lib/gis/handler.c
  3. \brief GIS Library - Error handlers
  4. (C) 2010-2011 by the GRASS Development Team
  5. This program is free software under the GNU General Public
  6. License (>=v2). Read the file COPYING that comes with GRASS
  7. for details.
  8. \author Glynn Clements
  9. */
  10. #include <stddef.h>
  11. #include <grass/gis.h>
  12. /*!
  13. \brief Error handler (see G_add_error_handler() for usage)
  14. */
  15. struct handler {
  16. /*!
  17. \brief Pointer to the handler routine
  18. */
  19. void (*func)(void *);
  20. /*!
  21. \brief Pointer to closure data
  22. */
  23. void *closure;
  24. };
  25. static struct handler *handlers;
  26. static int num_handlers;
  27. static int max_handlers;
  28. static struct handler *alloc_handler(void)
  29. {
  30. int i;
  31. for (i = 0; i < num_handlers; i++) {
  32. struct handler *h = &handlers[i];
  33. if (!h->func)
  34. return h;
  35. }
  36. if (num_handlers >= max_handlers) {
  37. max_handlers += 10;
  38. handlers = G_realloc(handlers, max_handlers * sizeof(struct handler));
  39. }
  40. return &handlers[num_handlers++];
  41. }
  42. /*!
  43. \brief Add new error handler
  44. Example
  45. \code
  46. static void error_handler(void *p) {
  47. const char *map = (const char *) p;
  48. Vect_delete(map);
  49. }
  50. G_add_error_handler(error_handler, new->answer);
  51. \endcode
  52. \param func handler to add
  53. \param closure pointer to closure data
  54. */
  55. void G_add_error_handler(void (*func)(void *), void *closure)
  56. {
  57. struct handler *h = alloc_handler();
  58. h->func = func;
  59. h->closure = closure;
  60. }
  61. /*!
  62. \brief Remove existing error handler
  63. \param func handler to be remove
  64. \param closure pointer to closure data
  65. */
  66. void G_remove_error_handler(void (*func)(void *), void *closure)
  67. {
  68. int i;
  69. for (i = 0; i < num_handlers; i++) {
  70. struct handler *h = &handlers[i];
  71. if (h->func == func && h->closure == closure) {
  72. h->func = NULL;
  73. h->closure = NULL;
  74. }
  75. }
  76. }
  77. /*!
  78. \brief Call available error handlers (internal use only)
  79. */
  80. void G__call_error_handlers(void)
  81. {
  82. int i;
  83. for (i = 0; i < num_handlers; i++) {
  84. struct handler *h = &handlers[i];
  85. if (h->func)
  86. (*h->func)(h->closure);
  87. }
  88. }