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  *      This file contains various utility functions
23  *
24  */
25 
26 #include "pgAdmin3.h"
27 #include "pgscript/utilities/mapm-lib/m_apm_lc.h"
28 
29 /****************************************************************************/
m_apm_sign(M_APM atmp)30 int	m_apm_sign(M_APM atmp)
31 {
32 	return(atmp->m_apm_sign);
33 }
34 /****************************************************************************/
m_apm_exponent(M_APM atmp)35 int	m_apm_exponent(M_APM atmp)
36 {
37 	if (atmp->m_apm_sign == 0)
38 		return(0);
39 	else
40 		return(atmp->m_apm_exponent - 1);
41 }
42 /****************************************************************************/
m_apm_significant_digits(M_APM atmp)43 int	m_apm_significant_digits(M_APM atmp)
44 {
45 	return(atmp->m_apm_datalength);
46 }
47 /****************************************************************************/
m_apm_is_integer(M_APM atmp)48 int	m_apm_is_integer(M_APM atmp)
49 {
50 	if (atmp->m_apm_sign == 0)
51 		return(1);
52 
53 	if (atmp->m_apm_exponent >= atmp->m_apm_datalength)
54 		return(1);
55 	else
56 		return(0);
57 }
58 /****************************************************************************/
m_apm_is_even(M_APM aa)59 int 	m_apm_is_even(M_APM aa)
60 {
61 	int     ii, jj;
62 
63 	if (aa->m_apm_sign == 0)
64 		return(1);
65 
66 	ii = aa->m_apm_datalength;
67 	jj = aa->m_apm_exponent;
68 
69 	if (jj < ii)
70 	{
71 		M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_is_even\', Non-integer input");
72 		return(0);
73 	}
74 
75 	if (jj > ii)
76 		return(1);
77 
78 	ii = ((ii + 1) >> 1) - 1;
79 	ii = (int)aa->m_apm_data[ii];
80 
81 	if ((jj & 1) != 0)      /* exponent is odd */
82 		ii = ii / 10;
83 
84 	if ((ii & 1) == 0)
85 		return(1);
86 	else
87 		return(0);
88 }
89 /****************************************************************************/
m_apm_is_odd(M_APM bb)90 int 	m_apm_is_odd(M_APM bb)
91 {
92 	if (m_apm_is_even(bb))
93 		return(0);
94 	else
95 		return(1);
96 }
97 /****************************************************************************/
M_set_to_zero(M_APM z)98 void	M_set_to_zero(M_APM z)
99 {
100 	z->m_apm_datalength = 1;
101 	z->m_apm_sign       = 0;
102 	z->m_apm_exponent   = 0;
103 	z->m_apm_data[0]    = 0;
104 }
105 /****************************************************************************/
m_apm_negate(M_APM d,M_APM s)106 void	m_apm_negate(M_APM d, M_APM s)
107 {
108 	m_apm_copy(d, s);
109 	if (d->m_apm_sign != 0)
110 		d->m_apm_sign = -(d->m_apm_sign);
111 }
112 /****************************************************************************/
m_apm_absolute_value(M_APM d,M_APM s)113 void	m_apm_absolute_value(M_APM d, M_APM s)
114 {
115 	m_apm_copy(d, s);
116 	if (d->m_apm_sign != 0)
117 		d->m_apm_sign = 1;
118 }
119 /****************************************************************************/
m_apm_copy(M_APM dest,M_APM src)120 void	m_apm_copy(M_APM dest, M_APM src)
121 {
122 	int	j;
123 	void	*vp;
124 
125 	j = (src->m_apm_datalength + 1) >> 1;
126 	if (j > dest->m_apm_malloclength)
127 	{
128 		if ((vp = MAPM_REALLOC(dest->m_apm_data, (j + 32))) == NULL)
129 		{
130 			/* fatal, this does not return */
131 
132 			M_apm_log_error_msg(M_APM_FATAL, "\'m_apm_copy\', Out of memory");
133 		}
134 
135 		dest->m_apm_malloclength = j + 28;
136 		dest->m_apm_data = (UCHAR *)vp;
137 	}
138 
139 	dest->m_apm_datalength = src->m_apm_datalength;
140 	dest->m_apm_exponent   = src->m_apm_exponent;
141 	dest->m_apm_sign       = src->m_apm_sign;
142 
143 	memcpy(dest->m_apm_data, src->m_apm_data, j);
144 }
145 /****************************************************************************/
m_apm_compare(M_APM ltmp,M_APM rtmp)146 int	m_apm_compare(M_APM ltmp, M_APM rtmp)
147 {
148 	int	llen, rlen, lsign, rsign, i, j, lexp, rexp;
149 
150 	llen  = ltmp->m_apm_datalength;
151 	rlen  = rtmp->m_apm_datalength;
152 
153 	lsign = ltmp->m_apm_sign;
154 	rsign = rtmp->m_apm_sign;
155 
156 	lexp  = ltmp->m_apm_exponent;
157 	rexp  = rtmp->m_apm_exponent;
158 
159 	if (rsign == 0)
160 		return(lsign);
161 
162 	if (lsign == 0)
163 		return(-rsign);
164 
165 	if (lsign == -rsign)
166 		return(lsign);
167 
168 	/* signs are the same, check the exponents */
169 
170 	if (lexp > rexp)
171 		goto E1;
172 
173 	if (lexp < rexp)
174 		goto E2;
175 
176 	/* signs and exponents are the same, check the data */
177 
178 	if (llen < rlen)
179 		j = (llen + 1) >> 1;
180 	else
181 		j = (rlen + 1) >> 1;
182 
183 	for (i = 0; i < j; i++)
184 	{
185 		if (ltmp->m_apm_data[i] > rtmp->m_apm_data[i])
186 			goto E1;
187 
188 		if (ltmp->m_apm_data[i] < rtmp->m_apm_data[i])
189 			goto E2;
190 	}
191 
192 	if (llen == rlen)
193 		return(0);
194 	else
195 	{
196 		if (llen > rlen)
197 			goto E1;
198 		else
199 			goto E2;
200 	}
201 
202 E1:
203 
204 	if (lsign == 1)
205 		return(1);
206 	else
207 		return(-1);
208 
209 E2:
210 
211 	if (lsign == 1)
212 		return(-1);
213 	else
214 		return(1);
215 }
216 /****************************************************************************/
217 /*
218  *
219  *	convert a signed long int to ASCII in base 10
220  *
221  */
M_long_2_ascii(char * output,long input)222 void    M_long_2_ascii(char *output, long input)
223 {
224 	long    t, m;
225 	int     i, j;
226 	char    *p, tbuf[64];
227 
228 	m = input;
229 	p = output;
230 	i = 0;
231 	t = 2147000000L;          /* something < 2^31 */
232 
233 	if ((m > t) || (m < -t))  /* handle the bigger numbers with 'sprintf'. */
234 	{
235 		/* let them worry about wrap-around problems */
236 		sprintf(p, "%ld", m);  /* at 'LONG_MIN', etc.                       */
237 	}
238 	else
239 	{
240 		if (m < 0)             /* handle the sign */
241 		{
242 			*p++ = '-';
243 			m = -m;
244 		}
245 
246 		while (TRUE)           /* build the digits in reverse order */
247 		{
248 			t = m / 10;
249 			j = (int)(m - (10 * t));
250 			tbuf[i++] = (char)(j + '0');
251 			m = t;
252 
253 			if (t == 0)
254 				break;
255 		}
256 
257 		while (TRUE)           /* fill output string in the correct order */
258 		{
259 			*p++ = tbuf[--i];
260 			if (i == 0)
261 				break;
262 		}
263 
264 		*p = '\0';
265 	}
266 }
267 /****************************************************************************/
268 /*
269  *      this function will convert a string to lowercase
270  */
M_lowercase(char * s)271 char    *M_lowercase(char *s)
272 {
273 	char    *p;
274 
275 	p = s;
276 
277 	while (TRUE)
278 	{
279 		if (*p >= 'A' && *p <= 'Z')
280 			*p += 'a' - 'A';
281 
282 		if (*p++ == '\0')  break;
283 	}
284 	return(s);
285 }
286 /****************************************************************************/
287 /*    returns char position of first occurrence of s2 in s1
288 	  or -1 if no match found
289 */
M_strposition(char * s1,char * s2)290 int     M_strposition(char *s1, char *s2)
291 {
292 	register char  ch1, ch2;
293 	char           *p0, *p1, *p2;
294 	int            ct;
295 
296 	ct = -1;
297 	p0 = s1;
298 
299 	if (*s2 == '\0')  return(-1);
300 
301 	while (TRUE)
302 	{
303 		ct++;
304 		p1  = p0;
305 		p2  = s2;
306 		ch2 = *p2;
307 
308 		while (TRUE)                    /* scan until first char matches */
309 		{
310 			if ((ch1 = *p1) == '\0')  return(-1);
311 			if (ch1 == ch2)           break;
312 			p1++;
313 			ct++;
314 		}
315 
316 		p2++;                           /* check remainder of 2 strings */
317 		p1++;
318 		p0 = p1;
319 
320 		while (TRUE)
321 		{
322 			if ((ch2 = *p2) == '\0')  return(ct);
323 			if (*p1 != ch2)           break;
324 			p1++;
325 			p2++;
326 		}
327 	}
328 }
329 /****************************************************************************/
330