Revert "wrap iconv_open / iconv_close with a lock to help in thread/fork issues"
[bpt/guile.git] / libguile / deprecation.c
CommitLineData
6a97b1f9 1/* Copyright (C) 2001, 2006, 2010, 2011, 2012 Free Software Foundation, Inc.
7e516288 2 *
73be1d9e 3 * This library is free software; you can redistribute it and/or
53befeb7
NJ
4 * modify it under the terms of the GNU Lesser General Public License
5 * as published by the Free Software Foundation; either version 3 of
6 * the License, or (at your option) any later version.
7e516288 7 *
53befeb7
NJ
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
7e516288 12 *
73be1d9e
MV
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
53befeb7
NJ
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301 USA
73be1d9e 17 */
7e516288
MV
18
19\f
20
dbb605f5 21#ifdef HAVE_CONFIG_H
5f0bcfd5
RB
22# include <config.h>
23#endif
24
7e516288 25#include <stdio.h>
fbbdb121 26#include <string.h>
d013f095 27#include <stdarg.h>
7e516288
MV
28
29#include "libguile/_scm.h"
30
31#include "libguile/deprecation.h"
7e516288
MV
32#include "libguile/strings.h"
33#include "libguile/ports.h"
34
22fc179a
HWN
35#include "libguile/private-options.h"
36
37
edb810bb
SJ
38/* Windows defines. */
39#ifdef __MINGW32__
40#define vsnprintf _vsnprintf
41#endif
42
7e516288
MV
43\f
44
d013f095
MV
45struct issued_warning {
46 struct issued_warning *prev;
47 const char *message;
48};
49
877514da 50static scm_i_pthread_mutex_t warn_lock = SCM_I_PTHREAD_MUTEX_INITIALIZER;
6a97b1f9 51SCM_PTHREAD_ATFORK_LOCK_STATIC_MUTEX (warn_lock);
d013f095 52static struct issued_warning *issued_warnings;
65bc1f7a 53static int print_summary = 0;
7e516288
MV
54
55void
56scm_c_issue_deprecation_warning (const char *msg)
57{
65bc1f7a
MV
58 if (!SCM_WARN_DEPRECATED)
59 print_summary = 1;
7e516288 60 else
d013f095
MV
61 {
62 struct issued_warning *iw;
877514da
AW
63
64 scm_i_pthread_mutex_lock (&warn_lock);
d013f095
MV
65 for (iw = issued_warnings; iw; iw = iw->prev)
66 if (!strcmp (iw->message, msg))
c46345e6
AW
67 {
68 msg = NULL;
69 break;
70 }
71 if (msg)
72 {
73 msg = strdup (msg);
74 iw = malloc (sizeof (struct issued_warning));
75 if (msg == NULL || iw == NULL)
76 /* Nothing sensible to do if you can't allocate this small
77 amount of memory. */
78 abort ();
79 iw->message = msg;
80 iw->prev = issued_warnings;
81 issued_warnings = iw;
82 }
877514da 83 scm_i_pthread_mutex_unlock (&warn_lock);
c46345e6
AW
84
85 /* All this dance is to avoid printing to a port inside a mutex,
86 which could recurse and deadlock. */
87 if (msg)
88 {
89 if (scm_gc_running_p)
90 fprintf (stderr, "%s\n", msg);
91 else
92 {
04ec290f 93 scm_puts_unlocked (msg, scm_current_warning_port ());
2c27dd57 94 scm_newline (scm_current_warning_port ());
c46345e6
AW
95 }
96 }
d013f095
MV
97 }
98}
99
100void
101scm_c_issue_deprecation_warning_fmt (const char *msg, ...)
102{
103 va_list ap;
104 char buf[512];
105
106 va_start (ap, msg);
107 vsnprintf (buf, 511, msg, ap);
11c47357 108 va_end (ap);
d013f095
MV
109 buf[511] = '\0';
110 scm_c_issue_deprecation_warning (buf);
7e516288
MV
111}
112
113SCM_DEFINE(scm_issue_deprecation_warning,
114 "issue-deprecation-warning", 0, 0, 1,
115 (SCM msgs),
116 "Output @var{msgs} to @code{(current-error-port)} when this "
117 "is the first call to @code{issue-deprecation-warning} with "
d013f095 118 "this specific @var{msgs}. Do nothing otherwise. "
7e516288
MV
119 "The argument @var{msgs} should be a list of strings; "
120 "they are printed in turn, each one followed by a newline.")
121#define FUNC_NAME s_scm_issue_deprecation_warning
122{
65bc1f7a
MV
123 if (!SCM_WARN_DEPRECATED)
124 print_summary = 1;
7e516288
MV
125 else
126 {
cc95e00a 127 SCM nl = scm_from_locale_string ("\n");
d013f095 128 SCM msgs_nl = SCM_EOL;
7f9994d9 129 char *c_msgs;
d2e53ed6 130 while (scm_is_pair (msgs))
7e516288 131 {
393baa8a 132 if (!scm_is_null (msgs_nl))
d013f095
MV
133 msgs_nl = scm_cons (nl, msgs_nl);
134 msgs_nl = scm_cons (SCM_CAR (msgs), msgs_nl);
135 msgs = SCM_CDR (msgs);
7e516288 136 }
d013f095 137 msgs_nl = scm_string_append (scm_reverse_x (msgs_nl, SCM_EOL));
7f9994d9
MV
138 c_msgs = scm_to_locale_string (msgs_nl);
139 scm_c_issue_deprecation_warning (c_msgs);
140 free (c_msgs);
7e516288
MV
141 }
142 return SCM_UNSPECIFIED;
143}
144#undef FUNC_NAME
145
146static void
147print_deprecation_summary (void)
148{
65bc1f7a 149 if (print_summary)
7e516288
MV
150 {
151 fputs ("\n"
152 "Some deprecated features have been used. Set the environment\n"
153 "variable GUILE_WARN_DEPRECATED to \"detailed\" and rerun the\n"
154 "program to get more information. Set it to \"no\" to suppress\n"
155 "this message.\n", stderr);
156 }
157}
158
7e516288
MV
159SCM_DEFINE(scm_include_deprecated_features,
160 "include-deprecated-features", 0, 0, 0,
161 (),
7bad99fd
MV
162 "Return @code{#t} iff deprecated features should be included "
163 "in public interfaces.")
7e516288
MV
164#define FUNC_NAME s_scm_include_deprecated_features
165{
7888309b 166 return scm_from_bool (SCM_ENABLE_DEPRECATED == 1);
7e516288
MV
167}
168#undef FUNC_NAME
169
170
171\f
172
173void
174scm_init_deprecation ()
175{
7e516288
MV
176 const char *level = getenv ("GUILE_WARN_DEPRECATED");
177 if (level == NULL)
887dfa7d 178 level = SCM_WARN_DEPRECATED_DEFAULT;
7e516288 179 if (!strcmp (level, "detailed"))
65bc1f7a 180 SCM_WARN_DEPRECATED = 1;
7e516288 181 else if (!strcmp (level, "no"))
65bc1f7a 182 SCM_WARN_DEPRECATED = 0;
7e516288
MV
183 else
184 {
65bc1f7a 185 SCM_WARN_DEPRECATED = 0;
7e516288
MV
186 atexit (print_deprecation_summary);
187 }
7e516288 188#include "libguile/deprecation.x"
7e516288
MV
189}
190
191/*
192 Local Variables:
193 c-file-style: "gnu"
53befeb7
NJ
194 End:
195 */