Added MACS source
[htsworkflow.git] / htswanalysis / MACS / lib / gsl / gsl-1.11 / ieee-utils / read.c
1 /* ieee-utils/read.c
2  * 
3  * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough
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 (at
8  * your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * 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
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19
20 #include <config.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <gsl/gsl_errno.h>
24 #include <gsl/gsl_ieee_utils.h>
25
26 static int 
27 lookup_string (const char * p, int * precision, int * rounding, 
28                int * exception_mask) ;
29
30 int
31 gsl_ieee_read_mode_string (const char * description, 
32                            int * precision, 
33                            int * rounding, 
34                            int * exception_mask)
35 {
36   char * start ;
37   char * end;
38   char * p;
39
40   int precision_count = 0 ;
41   int rounding_count = 0 ;
42   int exception_count = 0 ;
43
44   start = (char *) malloc(strlen(description) + 1) ;
45
46   if (start == 0) 
47     {
48       GSL_ERROR ("no memory to parse mode string", GSL_ENOMEM) ;
49     }
50
51   strcpy (start, description) ;
52
53   p = start ;
54
55   *precision = 0 ;
56   *rounding = 0 ;
57   *exception_mask = 0 ;
58
59   do {
60     int status ;
61     int new_precision, new_rounding, new_exception ;
62
63     end = strchr (p,',') ;
64
65     if (end) 
66       {
67         *end = '\0' ;
68         do 
69           {
70             end++ ;  /* skip over trailing whitespace */
71           } 
72         while (*end == ' ' || *end == ',') ;
73       }
74         
75     new_precision = 0 ; 
76     new_rounding = 0 ; 
77     new_exception = 0 ;
78
79     status = lookup_string (p, &new_precision, &new_rounding, &new_exception) ;
80
81     if (status)
82       GSL_ERROR ("unrecognized GSL_IEEE_MODE string.\nValid settings are:\n\n" 
83                  "  single-precision double-precision extended-precision\n"
84                  "  round-to-nearest round-down round-up round-to-zero\n"
85                  "  mask-invalid mask-denormalized mask-division-by-zero\n"
86                  "  mask-overflow mask-underflow mask-all\n"
87                  "  trap-common trap-inexact\n"
88                  "\n"
89                  "separated by commas. "
90                  "(e.g. GSL_IEEE_MODE=\"round-down,mask-underflow\")",
91                  GSL_EINVAL) ;
92
93     if (new_precision) 
94       {
95         *precision = new_precision ;
96         precision_count ++ ;
97         if (precision_count > 1)
98           GSL_ERROR ("attempted to set IEEE precision twice", GSL_EINVAL) ;
99       }
100
101     if (new_rounding) 
102       {
103         *rounding = new_rounding ;
104         rounding_count ++ ;
105         if (rounding_count > 1)
106           GSL_ERROR ("attempted to set IEEE rounding mode twice", GSL_EINVAL) ;
107       }
108
109     if (new_exception) 
110       {
111         *exception_mask |= new_exception ;
112         exception_count ++ ;
113       }
114
115     p = end ; 
116
117   } while (end && *p != '\0') ;
118
119   free(start) ;
120
121   return GSL_SUCCESS ;
122 }
123
124 static int 
125 lookup_string (const char * p, int * precision, int * rounding, 
126                int * exception_mask)
127 {
128   if (strcmp(p,"single-precision") == 0) 
129     {
130       *precision = GSL_IEEE_SINGLE_PRECISION ;
131     }
132   else if (strcmp(p,"double-precision") == 0) 
133     {
134       *precision = GSL_IEEE_DOUBLE_PRECISION ;
135     }
136   else if (strcmp(p,"extended-precision") == 0) 
137     {
138       *precision = GSL_IEEE_EXTENDED_PRECISION ;
139     }
140   else if (strcmp(p,"round-to-nearest") == 0) 
141     {
142       *rounding = GSL_IEEE_ROUND_TO_NEAREST ;
143     }
144   else if (strcmp(p,"round-down") == 0) 
145     {
146       *rounding = GSL_IEEE_ROUND_DOWN ;
147     }
148   else if (strcmp(p,"round-up") == 0) 
149     {
150       *rounding = GSL_IEEE_ROUND_UP ;
151     }
152   else if (strcmp(p,"round-to-zero") == 0) 
153     {
154       *rounding = GSL_IEEE_ROUND_TO_ZERO ;
155     }
156   else if (strcmp(p,"mask-all") == 0) 
157     {
158       *exception_mask = GSL_IEEE_MASK_ALL ;
159     }
160   else if (strcmp(p,"mask-invalid") == 0) 
161     {
162       *exception_mask = GSL_IEEE_MASK_INVALID ;
163     }
164   else if (strcmp(p,"mask-denormalized") == 0) 
165     {
166       *exception_mask = GSL_IEEE_MASK_DENORMALIZED ;
167     }
168   else if (strcmp(p,"mask-division-by-zero") == 0) 
169     {
170       *exception_mask = GSL_IEEE_MASK_DIVISION_BY_ZERO ;
171     }
172   else if (strcmp(p,"mask-overflow") == 0) 
173     {
174       *exception_mask = GSL_IEEE_MASK_OVERFLOW ;
175     }
176   else if (strcmp(p,"mask-underflow") == 0) 
177     {
178       *exception_mask = GSL_IEEE_MASK_UNDERFLOW ;
179     }
180   else if (strcmp(p,"trap-inexact") == 0) 
181     {
182       *exception_mask = GSL_IEEE_TRAP_INEXACT ;
183     }
184   else if (strcmp(p,"trap-common") == 0) 
185     {
186       return 0 ;
187     }
188   else
189     {
190       return 1 ;
191     }
192
193   return 0 ;
194 }