~vcs-imports/grub/grub2-bzr

« back to all changes in this revision

Viewing changes to grub-core/gnulib/msvc-inval.c

  • Committer: Vladimir 'phcoder' Serbinenko
  • Date: 2013-04-11 19:12:46 UTC
  • Revision ID: phcoder@gmail.com-20130411191246-fz1xdy47z3vv2kt8
        Import new gnulib.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Invalid parameter handler for MSVC runtime libraries.
 
2
   Copyright (C) 2011-2013 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 <http://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 &not_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 = &not_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