Annotation of embedaddon/libiconv/srclib/msvc-inval.c, revision 1.1.1.1
1.1 misho 1: /* Invalid parameter handler for MSVC runtime libraries.
2: Copyright (C) 2011-2019 Free Software Foundation, Inc.
3:
4: This program is free software; you can redistribute it and/or modify
5: it under the terms of the GNU General Public License as published by
6: the Free Software Foundation; either version 3, or (at your option)
7: any later version.
8:
9: This program is distributed in the hope that it will be useful,
10: but WITHOUT ANY WARRANTY; without even the implied warranty of
11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12: GNU General Public License for more details.
13:
14: You should have received a copy of the GNU General Public License along
15: with this program; if not, see <https://www.gnu.org/licenses/>. */
16:
17: #include <config.h>
18:
19: /* Specification. */
20: #include "msvc-inval.h"
21:
22: #if HAVE_MSVC_INVALID_PARAMETER_HANDLER \
23: && !(MSVC_INVALID_PARAMETER_HANDLING == SANE_LIBRARY_HANDLING)
24:
25: /* Get _invalid_parameter_handler type and _set_invalid_parameter_handler
26: declaration. */
27: # include <stdlib.h>
28:
29: # if MSVC_INVALID_PARAMETER_HANDLING == DEFAULT_HANDLING
30:
31: static void __cdecl
32: gl_msvc_invalid_parameter_handler (const wchar_t *expression,
33: const wchar_t *function,
34: const wchar_t *file,
35: unsigned int line,
36: uintptr_t dummy)
37: {
38: }
39:
40: # else
41:
42: /* Get declarations of the native Windows API functions. */
43: # define WIN32_LEAN_AND_MEAN
44: # include <windows.h>
45:
46: # if defined _MSC_VER
47:
48: static void __cdecl
49: gl_msvc_invalid_parameter_handler (const wchar_t *expression,
50: const wchar_t *function,
51: const wchar_t *file,
52: unsigned int line,
53: uintptr_t dummy)
54: {
55: RaiseException (STATUS_GNULIB_INVALID_PARAMETER, 0, 0, NULL);
56: }
57:
58: # else
59:
60: /* An index to thread-local storage. */
61: static DWORD tls_index;
62: static int tls_initialized /* = 0 */;
63:
64: /* Used as a fallback only. */
65: static struct gl_msvc_inval_per_thread not_per_thread;
66:
67: struct gl_msvc_inval_per_thread *
68: gl_msvc_inval_current (void)
69: {
70: if (!tls_initialized)
71: {
72: tls_index = TlsAlloc ();
73: tls_initialized = 1;
74: }
75: if (tls_index == TLS_OUT_OF_INDEXES)
76: /* TlsAlloc had failed. */
77: return ¬_per_thread;
78: else
79: {
80: struct gl_msvc_inval_per_thread *pointer =
81: (struct gl_msvc_inval_per_thread *) TlsGetValue (tls_index);
82: if (pointer == NULL)
83: {
84: /* First call. Allocate a new 'struct gl_msvc_inval_per_thread'. */
85: pointer =
86: (struct gl_msvc_inval_per_thread *)
87: malloc (sizeof (struct gl_msvc_inval_per_thread));
88: if (pointer == NULL)
89: /* Could not allocate memory. Use the global storage. */
90: pointer = ¬_per_thread;
91: TlsSetValue (tls_index, pointer);
92: }
93: return pointer;
94: }
95: }
96:
97: static void __cdecl
98: gl_msvc_invalid_parameter_handler (const wchar_t *expression,
99: const wchar_t *function,
100: const wchar_t *file,
101: unsigned int line,
102: uintptr_t dummy)
103: {
104: struct gl_msvc_inval_per_thread *current = gl_msvc_inval_current ();
105: if (current->restart_valid)
106: longjmp (current->restart, 1);
107: else
108: /* An invalid parameter notification from outside the gnulib code.
109: Give the caller a chance to intervene. */
110: RaiseException (STATUS_GNULIB_INVALID_PARAMETER, 0, 0, NULL);
111: }
112:
113: # endif
114:
115: # endif
116:
117: static int gl_msvc_inval_initialized /* = 0 */;
118:
119: void
120: gl_msvc_inval_ensure_handler (void)
121: {
122: if (gl_msvc_inval_initialized == 0)
123: {
124: _set_invalid_parameter_handler (gl_msvc_invalid_parameter_handler);
125: gl_msvc_inval_initialized = 1;
126: }
127: }
128:
129: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>