root/maint/gnulib/lib/msvc-inval.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gl_msvc_invalid_parameter_handler
  2. gl_msvc_invalid_parameter_handler
  3. gl_msvc_inval_current
  4. gl_msvc_invalid_parameter_handler
  5. gl_msvc_inval_ensure_handler

   1 /* Invalid parameter handler for MSVC runtime libraries.
   2    Copyright (C) 2011-2021 Free Software Foundation, Inc.
   3 
   4    This file is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU Lesser General Public License as
   6    published by the Free Software Foundation; either version 2.1 of the
   7    License, or (at your option) any later version.
   8 
   9    This file 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 Lesser General Public License for more details.
  13 
  14    You should have received a copy of the GNU Lesser General Public License
  15    along 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,
     /* [previous][next][first][last][top][bottom][index][help] */
  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,
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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,
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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

/* [previous][next][first][last][top][bottom][index][help] */