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 &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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>