xref: /haiku/src/libs/mapm/mapmutl2.c (revision 59d799dabcba86f92658ddb402f634e262d9aae7)
1 
2 /*
3  *  M_APM  -  mapmutl2.c
4  *
5  *  Copyright (C) 2002 - 2007   Michael C. Ring
6  *
7  *  Permission to use, copy, and distribute this software and its
8  *  documentation for any purpose with or without fee is hereby granted,
9  *  provided that the above copyright notice appear in all copies and
10  *  that both that copyright notice and this permission notice appear
11  *  in supporting documentation.
12  *
13  *  Permission to modify the software is granted. Permission to distribute
14  *  the modified code is granted. Modifications are to be distributed by
15  *  using the file 'license.txt' as a template to modify the file header.
16  *  'license.txt' is available in the official MAPM distribution.
17  *
18  *  This software is provided "as is" without express or implied warranty.
19  */
20 
21 /*
22  *      $Id: mapmutl2.c,v 1.7 2007/12/03 02:00:04 mike Exp $
23  *
24  *      This file contains various utility functions
25  *
26  *      $Log: mapmutl2.c,v $
27  *      Revision 1.7  2007/12/03 02:00:04  mike
28  *      Update license
29  *
30  *      Revision 1.6  2003/07/21 20:53:10  mike
31  *      Modify error messages to be in a consistent format.
32  *
33  *      Revision 1.5  2003/05/04 18:14:32  mike
34  *      move generic error handling function into a dedicated module
35  *
36  *      Revision 1.4  2003/03/31 22:02:22  mike
37  *      call generic error handling function
38  *
39  *      Revision 1.3  2002/11/03 21:19:40  mike
40  *      Updated function parameters to use the modern style
41  *
42  *      Revision 1.2  2002/05/17 22:29:46  mike
43  *      update some comments
44  *
45  *      Revision 1.1  2002/05/17 22:28:27  mike
46  *      Initial revision
47  */
48 
49 #include "m_apm_lc.h"
50 
51 /****************************************************************************/
m_apm_sign(M_APM atmp)52 int	m_apm_sign(M_APM atmp)
53 {
54 return(atmp->m_apm_sign);
55 }
56 /****************************************************************************/
m_apm_exponent(M_APM atmp)57 int	m_apm_exponent(M_APM atmp)
58 {
59 if (atmp->m_apm_sign == 0)
60   return(0);
61 else
62   return(atmp->m_apm_exponent - 1);
63 }
64 /****************************************************************************/
m_apm_significant_digits(M_APM atmp)65 int	m_apm_significant_digits(M_APM atmp)
66 {
67 return(atmp->m_apm_datalength);
68 }
69 /****************************************************************************/
m_apm_is_integer(M_APM atmp)70 int	m_apm_is_integer(M_APM atmp)
71 {
72 if (atmp->m_apm_sign == 0)
73   return(1);
74 
75 if (atmp->m_apm_exponent >= atmp->m_apm_datalength)
76   return(1);
77 else
78   return(0);
79 }
80 /****************************************************************************/
m_apm_is_even(M_APM aa)81 int 	m_apm_is_even(M_APM aa)
82 {
83 int     ii, jj;
84 
85 if (aa->m_apm_sign == 0)
86   return(1);
87 
88 ii = aa->m_apm_datalength;
89 jj = aa->m_apm_exponent;
90 
91 if (jj < ii)
92   {
93    M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_is_even\', Non-integer input");
94    return(0);
95   }
96 
97 if (jj > ii)
98   return(1);
99 
100 ii = ((ii + 1) >> 1) - 1;
101 ii = (int)aa->m_apm_data[ii];
102 
103 if ((jj & 1) != 0)      /* exponent is odd */
104   ii = ii / 10;
105 
106 if ((ii & 1) == 0)
107   return(1);
108 else
109   return(0);
110 }
111 /****************************************************************************/
m_apm_is_odd(M_APM bb)112 int 	m_apm_is_odd(M_APM bb)
113 {
114 if (m_apm_is_even(bb))
115   return(0);
116 else
117   return(1);
118 }
119 /****************************************************************************/
M_set_to_zero(M_APM z)120 void	M_set_to_zero(M_APM z)
121 {
122 z->m_apm_datalength = 1;
123 z->m_apm_sign       = 0;
124 z->m_apm_exponent   = 0;
125 z->m_apm_data[0]    = 0;
126 }
127 /****************************************************************************/
m_apm_negate(M_APM d,M_APM s)128 void	m_apm_negate(M_APM d, M_APM s)
129 {
130 m_apm_copy(d,s);
131 if (d->m_apm_sign != 0)
132     d->m_apm_sign = -(d->m_apm_sign);
133 }
134 /****************************************************************************/
m_apm_absolute_value(M_APM d,M_APM s)135 void	m_apm_absolute_value(M_APM d, M_APM s)
136 {
137 m_apm_copy(d,s);
138 if (d->m_apm_sign != 0)
139     d->m_apm_sign = 1;
140 }
141 /****************************************************************************/
m_apm_copy(M_APM dest,M_APM src)142 void	m_apm_copy(M_APM dest, M_APM src)
143 {
144 int	j;
145 void	*vp;
146 
147 j = (src->m_apm_datalength + 1) >> 1;
148 if (j > dest->m_apm_malloclength)
149   {
150    if ((vp = MAPM_REALLOC(dest->m_apm_data, (j + 32))) == NULL)
151      {
152       /* fatal, this does not return */
153 
154       M_apm_log_error_msg(M_APM_FATAL, "\'m_apm_copy\', Out of memory");
155      }
156 
157    dest->m_apm_malloclength = j + 28;
158    dest->m_apm_data = (UCHAR *)vp;
159   }
160 
161 dest->m_apm_datalength = src->m_apm_datalength;
162 dest->m_apm_exponent   = src->m_apm_exponent;
163 dest->m_apm_sign       = src->m_apm_sign;
164 
165 memcpy(dest->m_apm_data, src->m_apm_data, j);
166 }
167 /****************************************************************************/
m_apm_compare(M_APM ltmp,M_APM rtmp)168 int	m_apm_compare(M_APM ltmp, M_APM rtmp)
169 {
170 int	llen, rlen, lsign, rsign, i, j, lexp, rexp;
171 
172 llen  = ltmp->m_apm_datalength;
173 rlen  = rtmp->m_apm_datalength;
174 
175 lsign = ltmp->m_apm_sign;
176 rsign = rtmp->m_apm_sign;
177 
178 lexp  = ltmp->m_apm_exponent;
179 rexp  = rtmp->m_apm_exponent;
180 
181 if (rsign == 0)
182   return(lsign);
183 
184 if (lsign == 0)
185   return(-rsign);
186 
187 if (lsign == -rsign)
188   return(lsign);
189 
190 /* signs are the same, check the exponents */
191 
192 if (lexp > rexp)
193   goto E1;
194 
195 if (lexp < rexp)
196   goto E2;
197 
198 /* signs and exponents are the same, check the data */
199 
200 if (llen < rlen)
201   j = (llen + 1) >> 1;
202 else
203   j = (rlen + 1) >> 1;
204 
205 for (i=0; i < j; i++)
206   {
207    if (ltmp->m_apm_data[i] > rtmp->m_apm_data[i])
208      goto E1;
209 
210    if (ltmp->m_apm_data[i] < rtmp->m_apm_data[i])
211      goto E2;
212   }
213 
214 if (llen == rlen)
215    return(0);
216 else
217   {
218    if (llen > rlen)
219      goto E1;
220    else
221      goto E2;
222   }
223 
224 E1:
225 
226 if (lsign == 1)
227   return(1);
228 else
229   return(-1);
230 
231 E2:
232 
233 if (lsign == 1)
234   return(-1);
235 else
236   return(1);
237 }
238 /****************************************************************************/
239 /*
240  *
241  *	convert a signed long int to ASCII in base 10
242  *
243  */
M_long_2_ascii(char * output,long input)244 void    M_long_2_ascii(char *output, long input)
245 {
246 long    t, m;
247 int     i, j;
248 char    *p, tbuf[64];
249 
250 m = input;
251 p = output;
252 i = 0;
253 t = 2147000000L;          /* something < 2^31 */
254 
255 if ((m > t) || (m < -t))  /* handle the bigger numbers with 'sprintf'. */
256   {			  /* let them worry about wrap-around problems */
257    sprintf(p, "%ld", m);  /* at 'LONG_MIN', etc.                       */
258   }
259 else
260   {
261    if (m < 0)             /* handle the sign */
262      {
263       *p++ = '-';
264       m = -m;
265      }
266 
267    while (TRUE)           /* build the digits in reverse order */
268      {
269       t = m / 10;
270       j = (int)(m - (10 * t));
271       tbuf[i++] = (char)(j + '0');
272       m = t;
273 
274       if (t == 0)
275         break;
276      }
277 
278    while (TRUE)           /* fill output string in the correct order */
279      {
280       *p++ = tbuf[--i];
281       if (i == 0)
282         break;
283      }
284 
285    *p = '\0';
286   }
287 }
288 /****************************************************************************/
289 /*
290  *      this function will convert a string to lowercase
291  */
M_lowercase(char * s)292 char    *M_lowercase(char *s)
293 {
294 char    *p;
295 
296 p = s;
297 
298 while (TRUE)
299   {
300    if (*p >= 'A' && *p <= 'Z')
301      *p += 'a' - 'A';
302 
303    if (*p++ == '\0')  break;
304   }
305 return(s);
306 }
307 /****************************************************************************/
308 /*    returns char position of first occurence of s2 in s1
309 	  or -1 if no match found
310 */
M_strposition(char * s1,char * s2)311 int     M_strposition(char *s1, char *s2)
312 {
313 register char  ch1, ch2;
314 char           *p0, *p1, *p2;
315 int            ct;
316 
317 ct = -1;
318 p0 = s1;
319 
320 if (*s2 == '\0')  return(-1);
321 
322 while (TRUE)
323   {
324    ct++;
325    p1  = p0;
326    p2  = s2;
327    ch2 = *p2;
328 
329    while (TRUE)                    /* scan until first char matches */
330      {
331       if ((ch1 = *p1) == '\0')  return(-1);
332       if (ch1 == ch2)           break;
333       p1++;
334       ct++;
335      }
336 
337    p2++;                           /* check remainder of 2 strings */
338    p1++;
339    p0 = p1;
340 
341    while (TRUE)
342      {
343       if ((ch2 = *p2) == '\0')  return(ct);
344       if (*p1 != ch2)           break;
345       p1++;
346       p2++;
347      }
348   }
349 }
350 /****************************************************************************/
351