Imported Upstream version 0.19.7
[platform/upstream/gettext.git] / gettext-tools / src / plural-eval.c
1 /* Expression evaluation for plural form selection.
2    Copyright (C) 2000-2003, 2005, 2015 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 3 of the License, or
8    (at your option) 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, see <http://www.gnu.org/licenses/>.  */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 /* Specification.  */
23 #include "plural-eval.h"
24
25 #include <stddef.h>
26 #include <signal.h>
27
28 #include "plural-exp.h"
29
30
31 #define STATIC /*extern*/
32
33 /* Include the expression evaluation code from libintl, this time with
34    'extern' linkage.  */
35 #include "eval-plural.h"
36
37
38 /* Exit point.  Must be set before calling install_sigfpe_handler().  */
39 sigjmp_buf sigfpe_exit;
40
41 #if USE_SIGINFO
42
43 /* Additional information that is set before sigfpe_exit is invoked.  */
44 int sigfpe_code;
45
46 /* Signal handler called in case of arithmetic exception (e.g. division
47    by zero) during plural_eval.  */
48 static void
49 sigfpe_handler (int sig, siginfo_t *sip, void *scp)
50 {
51   sigfpe_code = sip->si_code;
52   siglongjmp (sigfpe_exit, 1);
53 }
54
55 #else
56
57 /* Signal handler called in case of arithmetic exception (e.g. division
58    by zero) during plural_eval.  */
59 static void
60 sigfpe_handler (int sig)
61 {
62   siglongjmp (sigfpe_exit, 1);
63 }
64
65 #endif
66
67 void
68 install_sigfpe_handler (void)
69 {
70 #if USE_SIGINFO
71   struct sigaction action;
72   action.sa_sigaction = sigfpe_handler;
73   action.sa_flags = SA_SIGINFO;
74   sigemptyset (&action.sa_mask);
75   sigaction (SIGFPE, &action, (struct sigaction *) NULL);
76 #else
77   signal (SIGFPE, sigfpe_handler);
78 #endif
79 }
80
81 void
82 uninstall_sigfpe_handler (void)
83 {
84 #if USE_SIGINFO
85   struct sigaction action;
86   action.sa_handler = SIG_DFL;
87   action.sa_flags = 0;
88   sigemptyset (&action.sa_mask);
89   sigaction (SIGFPE, &action, (struct sigaction *) NULL);
90 #else
91   signal (SIGFPE, SIG_DFL);
92 #endif
93 }