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