deprecation.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* Copyright (C) 2001, 2006 Free Software Foundation, Inc.
  2. *
  3. * This library is free software; you can redistribute it and/or
  4. * modify it under the terms of the GNU Lesser General Public
  5. * License as published by the Free Software Foundation; either
  6. * version 2.1 of the License, or (at your option) any later version.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * Lesser General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Lesser General Public
  14. * License along with this library; if not, write to the Free Software
  15. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  16. */
  17. #ifdef HAVE_CONFIG_H
  18. # include <config.h>
  19. #endif
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <stdarg.h>
  23. #include "libguile/_scm.h"
  24. #include "libguile/deprecation.h"
  25. #include "libguile/strings.h"
  26. #include "libguile/ports.h"
  27. /* Windows defines. */
  28. #ifdef __MINGW32__
  29. #define vsnprintf _vsnprintf
  30. #endif
  31. #if (SCM_ENABLE_DEPRECATED == 1)
  32. struct issued_warning {
  33. struct issued_warning *prev;
  34. const char *message;
  35. };
  36. static struct issued_warning *issued_warnings;
  37. static int print_summary = 0;
  38. void
  39. scm_c_issue_deprecation_warning (const char *msg)
  40. {
  41. if (!SCM_WARN_DEPRECATED)
  42. print_summary = 1;
  43. else
  44. {
  45. struct issued_warning *iw;
  46. for (iw = issued_warnings; iw; iw = iw->prev)
  47. if (!strcmp (iw->message, msg))
  48. return;
  49. if (scm_gc_running_p)
  50. fprintf (stderr, "%s\n", msg);
  51. else
  52. {
  53. scm_puts (msg, scm_current_error_port ());
  54. scm_newline (scm_current_error_port ());
  55. }
  56. msg = strdup (msg);
  57. iw = malloc (sizeof (struct issued_warning));
  58. if (msg == NULL || iw == NULL)
  59. return;
  60. iw->message = msg;
  61. iw->prev = issued_warnings;
  62. issued_warnings = iw;
  63. }
  64. }
  65. void
  66. scm_c_issue_deprecation_warning_fmt (const char *msg, ...)
  67. {
  68. va_list ap;
  69. char buf[512];
  70. va_start (ap, msg);
  71. vsnprintf (buf, 511, msg, ap);
  72. va_end (ap);
  73. buf[511] = '\0';
  74. scm_c_issue_deprecation_warning (buf);
  75. }
  76. SCM_DEFINE(scm_issue_deprecation_warning,
  77. "issue-deprecation-warning", 0, 0, 1,
  78. (SCM msgs),
  79. "Output @var{msgs} to @code{(current-error-port)} when this "
  80. "is the first call to @code{issue-deprecation-warning} with "
  81. "this specific @var{msgs}. Do nothing otherwise. "
  82. "The argument @var{msgs} should be a list of strings; "
  83. "they are printed in turn, each one followed by a newline.")
  84. #define FUNC_NAME s_scm_issue_deprecation_warning
  85. {
  86. if (!SCM_WARN_DEPRECATED)
  87. print_summary = 1;
  88. else
  89. {
  90. SCM nl = scm_from_locale_string ("\n");
  91. SCM msgs_nl = SCM_EOL;
  92. char *c_msgs;
  93. while (scm_is_pair (msgs))
  94. {
  95. if (msgs_nl != SCM_EOL)
  96. msgs_nl = scm_cons (nl, msgs_nl);
  97. msgs_nl = scm_cons (SCM_CAR (msgs), msgs_nl);
  98. msgs = SCM_CDR (msgs);
  99. }
  100. msgs_nl = scm_string_append (scm_reverse_x (msgs_nl, SCM_EOL));
  101. c_msgs = scm_to_locale_string (msgs_nl);
  102. scm_c_issue_deprecation_warning (c_msgs);
  103. free (c_msgs);
  104. }
  105. return SCM_UNSPECIFIED;
  106. }
  107. #undef FUNC_NAME
  108. static void
  109. print_deprecation_summary (void)
  110. {
  111. if (print_summary)
  112. {
  113. fputs ("\n"
  114. "Some deprecated features have been used. Set the environment\n"
  115. "variable GUILE_WARN_DEPRECATED to \"detailed\" and rerun the\n"
  116. "program to get more information. Set it to \"no\" to suppress\n"
  117. "this message.\n", stderr);
  118. }
  119. }
  120. #endif /* SCM_ENABLE_DEPRECATED == 1 */
  121. SCM_DEFINE(scm_include_deprecated_features,
  122. "include-deprecated-features", 0, 0, 0,
  123. (),
  124. "Return @code{#t} iff deprecated features should be included "
  125. "in public interfaces.")
  126. #define FUNC_NAME s_scm_include_deprecated_features
  127. {
  128. return scm_from_bool (SCM_ENABLE_DEPRECATED == 1);
  129. }
  130. #undef FUNC_NAME
  131. void
  132. scm_init_deprecation ()
  133. {
  134. #if (SCM_ENABLE_DEPRECATED == 1)
  135. const char *level = getenv ("GUILE_WARN_DEPRECATED");
  136. if (level == NULL)
  137. level = SCM_WARN_DEPRECATED_DEFAULT;
  138. if (!strcmp (level, "detailed"))
  139. SCM_WARN_DEPRECATED = 1;
  140. else if (!strcmp (level, "no"))
  141. SCM_WARN_DEPRECATED = 0;
  142. else
  143. {
  144. SCM_WARN_DEPRECATED = 0;
  145. atexit (print_deprecation_summary);
  146. }
  147. #endif
  148. #include "libguile/deprecation.x"
  149. }
  150. /*
  151. Local Variables:
  152. c-file-style: "gnu"
  153. End: */