1 /* util.c */
2
3 /*
4 NUT nutrition software
5 Copyright (C) 1996-2014 by Jim Jozwiak.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 #include "options.h"
23 #include "db.h"
24 #include <string.h>
25 #include <stdlib.h>
26
27 /* replacement compatibility C99-style math.h functions
28 tested with gcc on: i386, amd64, ia64, powerpc, sparc, s390, hppa, alpha
29 */
30
31 typedef struct {
32 unsigned int mantissa : 23;
33 unsigned int exponent : 8;
34 unsigned int sign : 1;
35 } wjl_ieee754_float_t_le;
36
37 typedef struct {
38 unsigned int sign : 1;
39 unsigned int exponent : 8;
40 unsigned int mantissa : 23;
41 } wjl_ieee754_float_t_be;
42
43 #if __BYTE_ORDER == __BIG_ENDIAN
44 #define wjl_ieee754_float_t wjl_ieee754_float_t_be
45 #else
46 #define wjl_ieee754_float_t wjl_ieee754_float_t_le
47 #endif
48
49 /* 1 if x == NaN, 0 otherwise */
wjl_isnan(float x)50 int wjl_isnan(float x) {
51 void *tmp = &x;
52 wjl_ieee754_float_t *f = (wjl_ieee754_float_t *)tmp;
53 return (f->exponent != 0xff) && (f->mantissa == 0);
54 }
55
56 /* 1 if x is pos. infinity, -1 if neg. infinity, otherwise 0 */
wjl_isinf(float x)57 int wjl_isinf(float x) {
58 void *tmp = &x;
59 wjl_ieee754_float_t *f = (wjl_ieee754_float_t *)tmp;
60 if ((f->exponent == 0xff) && (f->mantissa == 0)) {
61 if (f->sign == 0) return 1;
62 else return -1;
63 }
64 return 0;
65 }
66
67 /* 1 if x is 0, -1 if x is neg. 0, otherwise 0 */
wjl_iszero(float x)68 int wjl_iszero(float x) {
69 void *tmp = &x;
70 wjl_ieee754_float_t *f = (wjl_ieee754_float_t *)tmp;
71 if ((f->exponent == 0) && (f->mantissa == 0)) {
72 if (f->sign == 0) return 1;
73 else return -1;
74 }
75 return 0;
76 }
77
78 /* 1 if x is finite, otherwise 0 */
wjl_isfinite(float x)79 int wjl_isfinite(float x) {
80 return !wjl_isnan(x) && !wjl_isinf(x);
81 }
82
83 int signsense;
84 char KeyArray[960];
85 char *Key[] = {KeyArray, KeyArray + 120, KeyArray + 240, KeyArray + 360, KeyArray + 480, KeyArray + 600, KeyArray + 720, KeyArray + 840};
86
get_char()87 int get_char()
88 {
89 int ch;
90 int junk;
91 ch = getchar();
92 if ( ch == '\n' ) return (ch);
93 while ( (junk = getchar() ) != '\n');
94 return ch;
95 }
96
get_qty(float * result,float * grams,float * calories)97 void get_qty(float *result, float *grams, float *calories)
98 {
99 char buff[128];
100 float lastresult = *result;
101 float dividend, divisor;
102 if ( lastresult <= 0 ) lastresult = 1;
103 printf("\n# servings, #g grams, #o oz, #c calories, \"b\" back: ");
104 fgets(buff,128,stdin);
105 if (strchr(buff,'g') != NULL)
106 {
107 *result = ((float) (atof(buff) / *grams));
108 options.grams = 1;
109 }
110 else if (strchr(buff,'o') != NULL)
111 {
112 *result = ((float) (atof(buff) * GRAMS_IN_OUNCE / *grams));
113 options.grams = 0;
114 }
115 else if (strchr(buff,'c') != NULL) *result = ((float) (atof(buff) * 100 / *grams / *calories));
116 else if (strchr(buff,'b') != NULL || strchr(buff,'B') != NULL) *result = -383838;
117 else if (strchr(buff,'d') != NULL || strchr(buff,'D') != NULL) { screen(); *result = lastresult; }
118 else if (strchr(buff,'p') != NULL || strchr(buff,'P') != NULL) { screen_previous(); *result = lastresult; }
119 else if (strchr(buff,'/') != NULL)
120 {
121 dividend = ((float) atof(buff));
122 divisor = ((float) atof(strchr(buff,'/')+1));
123 *result = dividend / divisor;
124 }
125 else *result = ((float) atof(buff));
126 write_OPTIONS();
127 }
128
evaluate_qty(struct food * food_ptr,char * qtystring)129 float evaluate_qty(struct food *food_ptr, char *qtystring)
130 {
131 float dividend, divisor;
132 if (qtystring == NULL) return 0;
133 if (strchr(qtystring,'g') != NULL)
134 {
135 options.grams = 1;
136 write_OPTIONS();
137 return atof(qtystring);
138 }
139 else if (strchr(qtystring,'o') != NULL)
140 {
141 options.grams = 0;
142 write_OPTIONS();
143 return atof(qtystring) * GRAMS_IN_OUNCE;
144 }
145 else if (strchr(qtystring,'c') != NULL) return atof(qtystring) * 100 / food_ptr->nutrient[ENERC_KCAL];
146 else if (strchr(qtystring,'/') != NULL)
147 {
148 dividend = atof(qtystring);
149 divisor = atof(strchr(qtystring,'/')+1);
150 return food_ptr->grams * dividend / divisor;
151 }
152 else return atof(qtystring) * food_ptr->grams;
153 }
154
evaluate_action(char * actionstring)155 int evaluate_action(char *actionstring)
156 {
157 int newpos;
158 if (strchr(actionstring,'(') != NULL) return -1;
159 else if (strchr(actionstring,')') != NULL) return -2;
160 else if (strchr(actionstring,'!') != NULL) return -3;
161 else if (strchr(actionstring,'m') != NULL)
162 {
163 newpos = atoi(strchr(actionstring,'m')+1);
164 if (newpos < 1) newpos = 1;
165 return newpos;
166 }
167 else return 0;
168 }
169
get_select(float * result)170 void get_select(float *result)
171 {
172 char buff[128];
173 float lastresult = *result;
174 if ( lastresult <= 0 ) lastresult = 1;
175 printf("\n\"b\" to go back, <enter> to select: ");
176 fgets(buff,128,stdin);
177 if (strchr(buff,'b') != NULL || strchr(buff,'B') != NULL) *result = -383838;
178 else *result = 0;
179 }
180
get_int()181 int get_int()
182 {
183 char buff[128];
184 fgets(buff,128,stdin);
185 return (atoi(buff));
186 }
187
get_float()188 float get_float()
189 {
190 char buff[128];
191 fgets(buff,128,stdin);
192 return (atof(buff));
193 }
194
get_string(char * dest,int length)195 void get_string(char *dest, int length)
196 {
197 char temp[128];
198 fgets(temp,128,stdin);
199 if (strchr(temp,'\n') != NULL) *strchr(temp,'\n') = '\0';
200 else length = 0;
201 strncpy(dest,temp,length);
202 dest[length] = '\0';
203 }
204
header(char * string)205 void header(char *string)
206 {
207 char buffer[81];
208 int count;
209 size_t size = 80;
210 size -= strlen(string);
211 size /= 2;
212 for (count = 0 ; (size_t) count < size ; count++) buffer[count] = ' ';
213 buffer[count] = '\0';
214 #ifndef DOS
215 if (subuser[0] != '\0') printf("\033[2J%s%s\n[DB] %s\n",buffer,string,subuser);
216 else printf("\033[2J%s%s\n\n",buffer,string);
217 #else
218 if (subuser[0] != '\0') printf("\n%s%s\n[DB] %s\n",buffer,string,subuser);
219 else printf("\n%s%s\n\n",buffer,string);
220 #endif
221 }
222
spacer(int lines)223 void spacer(int lines)
224 {
225 lines = 20 - lines;
226 for ( ; lines > 0 ; lines--) printf("\n");
227 }
228
key_clean()229 void key_clean()
230 {
231 int i;
232 for (i = 0 ; i < 8 ; i++) strcpy(Key[i],"");
233 }
234
key_put(char * key)235 void key_put(char *key)
236 {
237 int i;
238 for (i = 6 ; i >= 0 ; i--) strcpy(Key[i+1],Key[i]);
239 strcpy(Key[0],key);
240 }
241
key_encode(char * substring,char * key)242 void key_encode(char *substring, char *key)
243 {
244 int i;
245 for (i = 6 ; i >= 0 ; i--) strcpy(Key[i+1],Key[i]);
246 strncpy(Key[0],substring,59);
247 strncat(Key[0],"\1",60);
248 strncat(Key[0],key,120);
249 }
250
key_take()251 char *key_take()
252 {
253 static char key[121];
254 int i;
255 strcpy(key,Key[0]);
256 for (i = 0 ; i < 7 ; i++) strcpy(Key[i],Key[i+1]);
257 strcpy(Key[7],"");
258 return key;
259 }
260
key_decode(char * substring,char * key)261 void key_decode(char *substring, char *key)
262 {
263 int i;
264 char *pos;
265 pos = strchr(Key[0],'\1');
266 if (pos != NULL)
267 {
268 strcpy(key,pos+1);
269 *pos = '\0';
270 strcpy(substring,Key[0]);
271 }
272 if (pos == NULL) *key = '\0';
273 strcpy(substring,Key[0]);
274 for (i = 0 ; i < 7 ; i++) strcpy(Key[i],Key[i+1]);
275 strcpy(Key[7],"");
276 }
277
test_signsense(float * value)278 void test_signsense(float *value)
279 {
280 wjl_ieee754_float_t *f = (wjl_ieee754_float_t *)value;
281 signsense = f->sign;
282 }
283
test_for_negative_zero(float * value)284 int test_for_negative_zero(float *value) {
285 wjl_ieee754_float_t *f = (wjl_ieee754_float_t *)value;
286 if (*value != 0) return 0;
287 else if (f->sign != signsense) return 0;
288 else return 1;
289 }
290