xref: /netbsd-src/external/gpl2/gettext/dist/gettext-tools/src/plural-eval.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1 /* Expression evaluation for plural form selection.
2    Copyright (C) 2000-2003, 2005 Free Software Foundation, Inc.
3    Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2, or (at your option)
8    any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software Foundation,
17    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
18 
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22 
23 /* Specification.  */
24 #include "plural-eval.h"
25 
26 #include <stddef.h>
27 #include <signal.h>
28 
29 #include "plural-exp.h"
30 
31 
32 #define STATIC /*extern*/
33 
34 /* Include the expression evaluation code from libintl, this time with
35    'extern' linkage.  */
36 #include "eval-plural.h"
37 
38 
39 /* Exit point.  Must be set before calling install_sigfpe_handler().  */
40 sigjmp_buf sigfpe_exit;
41 
42 #if USE_SIGINFO
43 
44 /* Additional information that is set before sigfpe_exit is invoked.  */
45 int sigfpe_code;
46 
47 /* Signal handler called in case of arithmetic exception (e.g. division
48    by zero) during plural_eval.  */
49 static void
sigfpe_handler(int sig,siginfo_t * sip,void * scp)50 sigfpe_handler (int sig, siginfo_t *sip, void *scp)
51 {
52   sigfpe_code = sip->si_code;
53   siglongjmp (sigfpe_exit, 1);
54 }
55 
56 #else
57 
58 /* Signal handler called in case of arithmetic exception (e.g. division
59    by zero) during plural_eval.  */
60 static void
sigfpe_handler(int sig)61 sigfpe_handler (int sig)
62 {
63   siglongjmp (sigfpe_exit, 1);
64 }
65 
66 #endif
67 
68 void
install_sigfpe_handler(void)69 install_sigfpe_handler (void)
70 {
71 #if USE_SIGINFO
72   struct sigaction action;
73   action.sa_sigaction = sigfpe_handler;
74   action.sa_flags = SA_SIGINFO;
75   sigemptyset (&action.sa_mask);
76   sigaction (SIGFPE, &action, (struct sigaction *) NULL);
77 #else
78   signal (SIGFPE, sigfpe_handler);
79 #endif
80 }
81 
82 void
uninstall_sigfpe_handler(void)83 uninstall_sigfpe_handler (void)
84 {
85 #if USE_SIGINFO
86   struct sigaction action;
87   action.sa_handler = SIG_DFL;
88   action.sa_flags = 0;
89   sigemptyset (&action.sa_mask);
90   sigaction (SIGFPE, &action, (struct sigaction *) NULL);
91 #else
92   signal (SIGFPE, SIG_DFL);
93 #endif
94 }
95