~ubuntu-branches/debian/sid/pgadmin3/sid

« back to all changes in this revision

Viewing changes to pgadmin/pgscript/utilities/m_apm/mapm_set.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Gerfried Fuchs
  • Date: 2009-07-30 12:27:16 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090730122716-fddbh42on721bbs2
Tags: 1.10.0-1
* New upstream release.
* Adjusted watch file to match release candidates.
* Updated to Standards-Version 3.8.2:
  - Moved to Section: database.
  - Add DEB_BUILD_OPTIONS support for parallel building.
  - Move from findstring to filter suggestion for DEB_BUILD_OPTIONS parsing.
* pgagent got split into its own separate source package by upstream.
* Exclude Docs.vcproj from installation.
* Move doc-base.enus from pgadmin3 to pgadmin3-data package, the files are
  in there too.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* 
 
3
 *  M_APM  -  mapm_set.c
 
4
 *
 
5
 *  Copyright (C) 1999 - 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
 *
 
23
 *      This file contains the functions necessary to get C 'longs' and
 
24
 *      'strings' into the MAPM number system. It also contains the function
 
25
 *      to get a string from a MAPM number.
 
26
 *
 
27
 */
 
28
 
 
29
#include "pgAdmin3.h"
 
30
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
 
31
 
 
32
static  char *M_buf  = NULL;
 
33
static  int   M_lbuf = 0;
 
34
static  const char *M_set_string_error_msg = "\'m_apm_set_string\', Out of memory";
 
35
 
 
36
/****************************************************************************/
 
37
void    M_free_all_set()
 
38
{
 
39
if (M_lbuf != 0)
 
40
  {
 
41
   MAPM_FREE(M_buf);
 
42
   M_buf  = NULL;
 
43
   M_lbuf = 0;
 
44
  }
 
45
}
 
46
/****************************************************************************/
 
47
void    m_apm_set_long(M_APM atmp, long mm)
 
48
{
 
49
int     len, ii, nbytes;
 
50
char    *p, *buf, ch, buf2[64];
 
51
 
 
52
/* if zero, return right away */
 
53
 
 
54
if (mm == 0)
 
55
  {
 
56
   M_set_to_zero(atmp);
 
57
   return;
 
58
  }
 
59
 
 
60
M_long_2_ascii(buf2, mm);     /* convert long -> ascii in base 10 */
 
61
buf = buf2;
 
62
 
 
63
if (mm < 0)
 
64
  {
 
65
   atmp->m_apm_sign = -1;
 
66
   buf++;                     /* get past '-' sign */
 
67
  }
 
68
else
 
69
  {
 
70
   atmp->m_apm_sign = 1;
 
71
  }
 
72
 
 
73
len = strlen(buf);
 
74
atmp->m_apm_exponent = len;
 
75
 
 
76
/* least significant nibble of ODD data-length must be 0 */
 
77
 
 
78
if ((len & 1) != 0)
 
79
  {
 
80
   buf[len] = '0';
 
81
  }
 
82
 
 
83
/* remove any trailing '0' ... */
 
84
 
 
85
while (TRUE)
 
86
  {
 
87
   if (buf[--len] != '0')
 
88
     break;
 
89
  }
 
90
 
 
91
atmp->m_apm_datalength = ++len;
 
92
 
 
93
nbytes = (len + 1) >> 1;
 
94
p = buf;
 
95
 
 
96
for (ii=0; ii < nbytes; ii++)
 
97
  {
 
98
   ch = *p++ - '0';
 
99
   atmp->m_apm_data[ii] = 10 * ch + *p++ - '0';
 
100
  }
 
101
}
 
102
/****************************************************************************/
 
103
void    m_apm_set_string(M_APM ctmp, const char *s_in)
 
104
{
 
105
char    ch, *cp, *s, *p;
 
106
void    *vp;
 
107
int     i, j, zflag, exponent, sign;
 
108
 
 
109
if (M_lbuf == 0)
 
110
  {
 
111
   M_lbuf = 256;
 
112
   if ((M_buf = (char *)MAPM_MALLOC(256)) == NULL)
 
113
     {
 
114
      /* fatal, this does not return */
 
115
 
 
116
      M_apm_log_error_msg(M_APM_FATAL, M_set_string_error_msg);
 
117
     }
 
118
  }
 
119
 
 
120
if ((i = strlen(s_in)) > (M_lbuf - 4))
 
121
  {
 
122
   M_lbuf = i + 32;
 
123
   if ((vp = MAPM_REALLOC(M_buf, M_lbuf)) == NULL)
 
124
     {
 
125
      /* fatal, this does not return */
 
126
 
 
127
      M_apm_log_error_msg(M_APM_FATAL, M_set_string_error_msg);
 
128
     }
 
129
 
 
130
   M_buf = (char *)vp;
 
131
  }
 
132
 
 
133
s = M_buf;
 
134
strcpy(s,s_in);
 
135
 
 
136
/* default == zero ... */
 
137
 
 
138
M_set_to_zero(ctmp);
 
139
 
 
140
p = s;
 
141
 
 
142
while (TRUE)
 
143
  {
 
144
   if (*p == ' ' || *p == '\t')
 
145
     p++;
 
146
   else
 
147
     break;
 
148
  }
 
149
 
 
150
if (*p == '\0')
 
151
  return;
 
152
 
 
153
sign = 1;             /* assume number is positive */
 
154
 
 
155
if (*p == '+')        /* scan by optional '+' sign */
 
156
  p++;
 
157
else
 
158
  {
 
159
   if (*p == '-')     /* check if number negative */
 
160
     {
 
161
      sign = -1;
 
162
      p++;
 
163
     }
 
164
  }
 
165
 
 
166
M_lowercase(p);       /* convert string to lowercase */
 
167
exponent = 0;         /* default */
 
168
   
 
169
if ((cp = strstr(p,"e")) != NULL)
 
170
  {
 
171
   exponent = atoi(cp + sizeof(char));
 
172
   *cp = '\0';          /* erase the exponent now */
 
173
  }
 
174
 
 
175
j = M_strposition(p, (char *) ".");        /* is there a decimal point ?? */
 
176
if (j == -1)
 
177
  {
 
178
   strcat(p,".");                /* if not, append one */
 
179
   j = M_strposition(p, (char *) ".");     /* now find it ... */
 
180
  }
 
181
 
 
182
if (j > 0)                       /* normalize number and adjust exponent */
 
183
  {
 
184
   exponent += j;
 
185
   memmove((p+1),p,(j * sizeof(char)));
 
186
  }
 
187
 
 
188
p++;        /* scan past implied decimal point now in column 1 (index 0) */
 
189
 
 
190
i = strlen(p);
 
191
ctmp->m_apm_datalength = i;
 
192
 
 
193
if ((i & 1) != 0)   /* if odd number of digits, append a '0' to make it even */
 
194
  strcat(p,"0");    
 
195
 
 
196
j = strlen(p) >> 1;  /* number of bytes in encoded M_APM number */
 
197
 
 
198
/* do we need more memory to hold this number */
 
199
 
 
200
if (j > ctmp->m_apm_malloclength)
 
201
  {
 
202
   if ((vp = MAPM_REALLOC(ctmp->m_apm_data, (j + 32))) == NULL)
 
203
     {
 
204
      /* fatal, this does not return */
 
205
 
 
206
      M_apm_log_error_msg(M_APM_FATAL, M_set_string_error_msg);
 
207
     }
 
208
  
 
209
   ctmp->m_apm_malloclength = j + 28;
 
210
   ctmp->m_apm_data = (UCHAR *)vp;
 
211
  }
 
212
 
 
213
zflag = TRUE;
 
214
 
 
215
for (i=0; i < j; i++)
 
216
  {
 
217
   ch = *p++ - '0';
 
218
   if ((ch = (10 * ch + *p++ - '0')) != 0)
 
219
     zflag = FALSE;
 
220
 
 
221
   if (((int)ch & 0xFF) >= 100)
 
222
     {
 
223
      M_apm_log_error_msg(M_APM_RETURN,
 
224
      "\'m_apm_set_string\', Non-digit char found in parse");
 
225
 
 
226
      M_apm_log_error_msg(M_APM_RETURN, "Text =");
 
227
      M_apm_log_error_msg(M_APM_RETURN, s_in);
 
228
 
 
229
      M_set_to_zero(ctmp);
 
230
      return;
 
231
     }
 
232
 
 
233
   ctmp->m_apm_data[i]   = ch;
 
234
   ctmp->m_apm_data[i+1] = 0;
 
235
  }
 
236
 
 
237
ctmp->m_apm_exponent = exponent;
 
238
ctmp->m_apm_sign     = sign;
 
239
 
 
240
if (zflag)
 
241
  {
 
242
   ctmp->m_apm_exponent   = 0;
 
243
   ctmp->m_apm_sign       = 0;
 
244
   ctmp->m_apm_datalength = 1;
 
245
  }
 
246
else
 
247
  {
 
248
   M_apm_normalize(ctmp);
 
249
  }
 
250
 
 
251
/*
 
252
 *  if our local temp string is getting too big,
 
253
 *  release it's memory and start over next time.
 
254
 *  (this 1000 byte threshold is quite arbitrary,
 
255
 *  it may be more efficient in your app to make
 
256
 *  this number bigger).
 
257
 */
 
258
 
 
259
if (M_lbuf > 1000)
 
260
  {
 
261
   MAPM_FREE(M_buf);
 
262
   M_buf  = NULL;
 
263
   M_lbuf = 0;
 
264
  }
 
265
}
 
266
/****************************************************************************/
 
267
void    m_apm_to_string(char *s, int places, M_APM mtmp)
 
268
{
 
269
M_APM   ctmp;
 
270
char    *cp;
 
271
int     i, index, first, max_i, num_digits, dec_places;
 
272
UCHAR   numdiv, numrem;
 
273
 
 
274
ctmp = M_get_stack_var();
 
275
dec_places = places;
 
276
 
 
277
if (dec_places < 0)
 
278
  m_apm_copy(ctmp, mtmp);
 
279
else
 
280
  m_apm_round(ctmp, dec_places, mtmp);
 
281
 
 
282
if (ctmp->m_apm_sign == 0)
 
283
  {
 
284
   if (dec_places < 0)
 
285
      strcpy(s,"0.0E+0");
 
286
   else
 
287
     {
 
288
      strcpy(s,"0");
 
289
 
 
290
      if (dec_places > 0)
 
291
        strcat(s,".");
 
292
 
 
293
      for (i=0; i < dec_places; i++)
 
294
        strcat(s,"0");
 
295
 
 
296
      strcat(s,"E+0");
 
297
     }
 
298
 
 
299
   M_restore_stack(1);
 
300
   return;
 
301
  }
 
302
 
 
303
max_i = (ctmp->m_apm_datalength + 1) >> 1;
 
304
 
 
305
if (dec_places < 0)
 
306
  num_digits = ctmp->m_apm_datalength;
 
307
else
 
308
  num_digits = dec_places + 1;
 
309
 
 
310
cp = s;
 
311
 
 
312
if (ctmp->m_apm_sign == -1)
 
313
  *cp++ = '-';
 
314
 
 
315
first = TRUE;
 
316
 
 
317
i = 0;
 
318
index = 0;
 
319
 
 
320
while (TRUE)
 
321
  {
 
322
   if (index >= max_i)
 
323
     {
 
324
      numdiv = 0;
 
325
      numrem = 0;
 
326
     }
 
327
   else
 
328
      M_get_div_rem_10((int)ctmp->m_apm_data[index],&numdiv,&numrem);
 
329
 
 
330
   index++;
 
331
 
 
332
   *cp++ = numdiv + '0';
 
333
 
 
334
   if (++i == num_digits)
 
335
     break;
 
336
 
 
337
   if (first)
 
338
     {
 
339
      first = FALSE;
 
340
      *cp++ = '.';
 
341
     }
 
342
 
 
343
   *cp++ = numrem + '0';
 
344
 
 
345
   if (++i == num_digits)
 
346
     break;
 
347
  }
 
348
 
 
349
i = ctmp->m_apm_exponent - 1;
 
350
if (i >= 0)
 
351
  sprintf(cp,"E+%d",i);
 
352
else
 
353
  sprintf(cp,"E%d",i);
 
354
 
 
355
M_restore_stack(1);
 
356
}
 
357
/****************************************************************************/