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