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