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, |
| 1Start Analysis. |
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) ; |
| 2Call a function.    strlen(description) |
| 3Call a function.    malloc(strlen(description) + 1) |
| 48Memory allocated in heap space is not freed.    malloc(strlen(description) + 1) |
45 | |
46 | if (start == 0) |
| 4Take the false branch.    start == 0 |
47 | { |
48 | GSL_ERROR ("no memory to parse mode string", GSL_ENOMEM) ; |
49 | } |
50 | |
51 | strcpy (start, description) ; |
| 5Call a function.    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,',') ; |
| 6Call a function.    strchr(p, ',') |
64 | |
65 | if (end) |
| 7Take the true branch.    end |
66 | { |
67 | *end = '\0' ; |
68 | do |
69 | { |
70 | end++ ; /* skip over trailing whitespace */ |
71 | } |
72 | while (*end == ' ' || *end == ',') ; |
| 8Take the false branch.    *end == ' ' |
| 9Take the false branch.    *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) ; |
| 10Call a function.    lookup_string(p, &new_precision, &new_rounding, &new_exception) |
80 | |
81 | if (status) |
| 43Take the true branch.    status |
82 | GSL_ERROR ("unrecognized GSL_IEEE_MODE string.\nValid settings are:\n\n" |
| 44Call a function.    gsl_error("unrecognized GSL_IEEE_MODE string.\nValid settings are:\n\n single-precision double-precision extended-precision\n round-to-nearest round-down round-up round-to-zero\n mask-invalid mask-denormalized mask-division-by-zero\n mask-overflow mask-underflow mask-all\n trap-common trap-inexact\n\nseparated by commas. (e.g. GSL_IEEE_MODE=\"round-down,mask-underflow\")", "/home/xingming/workplace/experiment/fp/gsl-2.1/ieee-utils/read.c", 91, GSL_EINVAL) |
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, |
| 11Enter function.    lookup_string(p, &new_precision, &new_rounding, &new_exception) |
126 | int * exception_mask) |
127 | { |
128 | if (strcmp(p,"single-precision") == 0) |
| 12Call a function.    strcmp(p, "single-precision") |
| 13Take the false branch.    strcmp(p, "single-precision") == 0 |
129 | { |
130 | *precision = GSL_IEEE_SINGLE_PRECISION ; |
131 | } |
132 | else if (strcmp(p,"double-precision") == 0) |
| 14Call a function.    strcmp(p, "double-precision") |
| 15Take the false branch.    strcmp(p, "double-precision") == 0 |
133 | { |
134 | *precision = GSL_IEEE_DOUBLE_PRECISION ; |
135 | } |
136 | else if (strcmp(p,"extended-precision") == 0) |
| 16Call a function.    strcmp(p, "extended-precision") |
| 17Take the false branch.    strcmp(p, "extended-precision") == 0 |
137 | { |
138 | *precision = GSL_IEEE_EXTENDED_PRECISION ; |
139 | } |
140 | else if (strcmp(p,"round-to-nearest") == 0) |
| 18Call a function.    strcmp(p, "round-to-nearest") |
| 19Take the false branch.    strcmp(p, "round-to-nearest") == 0 |
141 | { |
142 | *rounding = GSL_IEEE_ROUND_TO_NEAREST ; |
143 | } |
144 | else if (strcmp(p,"round-down") == 0) |
| 20Call a function.    strcmp(p, "round-down") |
| 21Take the false branch.    strcmp(p, "round-down") == 0 |
145 | { |
146 | *rounding = GSL_IEEE_ROUND_DOWN ; |
147 | } |
148 | else if (strcmp(p,"round-up") == 0) |
| 22Call a function.    strcmp(p, "round-up") |
| 23Take the false branch.    strcmp(p, "round-up") == 0 |
149 | { |
150 | *rounding = GSL_IEEE_ROUND_UP ; |
151 | } |
152 | else if (strcmp(p,"round-to-zero") == 0) |
| 24Call a function.    strcmp(p, "round-to-zero") |
| 25Take the false branch.    strcmp(p, "round-to-zero") == 0 |
153 | { |
154 | *rounding = GSL_IEEE_ROUND_TO_ZERO ; |
155 | } |
156 | else if (strcmp(p,"mask-all") == 0) |
| 26Call a function.    strcmp(p, "mask-all") |
| 27Take the false branch.    strcmp(p, "mask-all") == 0 |
157 | { |
158 | *exception_mask = GSL_IEEE_MASK_ALL ; |
159 | } |
160 | else if (strcmp(p,"mask-invalid") == 0) |
| 28Call a function.    strcmp(p, "mask-invalid") |
| 29Take the false branch.    strcmp(p, "mask-invalid") == 0 |
161 | { |
162 | *exception_mask = GSL_IEEE_MASK_INVALID ; |
163 | } |
164 | else if (strcmp(p,"mask-denormalized") == 0) |
| 30Call a function.    strcmp(p, "mask-denormalized") |
| 31Take the false branch.    strcmp(p, "mask-denormalized") == 0 |
165 | { |
166 | *exception_mask = GSL_IEEE_MASK_DENORMALIZED ; |
167 | } |
168 | else if (strcmp(p,"mask-division-by-zero") == 0) |
| 32Call a function.    strcmp(p, "mask-division-by-zero") |
| 33Take the false branch.    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) |
| 34Call a function.    strcmp(p, "mask-overflow") |
| 35Take the false branch.    strcmp(p, "mask-overflow") == 0 |
173 | { |
174 | *exception_mask = GSL_IEEE_MASK_OVERFLOW ; |
175 | } |
176 | else if (strcmp(p,"mask-underflow") == 0) |
| 36Call a function.    strcmp(p, "mask-underflow") |
| 37Take the false branch.    strcmp(p, "mask-underflow") == 0 |
177 | { |
178 | *exception_mask = GSL_IEEE_MASK_UNDERFLOW ; |
179 | } |
180 | else if (strcmp(p,"trap-inexact") == 0) |
| 38Call a function.    strcmp(p, "trap-inexact") |
| 39Take the false branch.    strcmp(p, "trap-inexact") == 0 |
181 | { |
182 | *exception_mask = GSL_IEEE_TRAP_INEXACT ; |
183 | } |
184 | else if (strcmp(p,"trap-common") == 0) |
| 40Call a function.    strcmp(p, "trap-common") |
| 41Take the false branch.    strcmp(p, "trap-common") == 0 |
185 | { |
186 | return 0 ; |
187 | } |
188 | else |
189 | { |
190 | return 1 ; |
191 | } |
192 | |
193 | return 0 ; |
194 | } |
| 42Exit function.    lookup_string(p, &new_precision, &new_rounding, &new_exception) |
195 | |