~ubuntu-branches/ubuntu/karmic/firebird2.1/karmic

« back to all changes in this revision

Viewing changes to src/extlib/ib_udf.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Damyan Ivanov
  • Date: 2008-05-26 23:59:25 UTC
  • Revision ID: james.westby@ubuntu.com-20080526235925-2pnqj6nxpppoeaer
Tags: upstream-2.1.0.17798-0.ds2
ImportĀ upstreamĀ versionĀ 2.1.0.17798-0.ds2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * The contents of this file are subject to the Interbase Public
 
3
 * License Version 1.0 (the "License"); you may not use this file
 
4
 * except in compliance with the License. You may obtain a copy
 
5
 * of the License at http://www.Inprise.com/IPL.html
 
6
 *
 
7
 * Software distributed under the License is distributed on an
 
8
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 
9
 * or implied. See the License for the specific language governing
 
10
 * rights and limitations under the License.
 
11
 *
 
12
 * The Original Code was created by Inprise Corporation
 
13
 * and its predecessors. Portions created by Inprise Corporation are
 
14
 * Copyright (C) Inprise Corporation.
 
15
 *
 
16
 * All Rights Reserved.
 
17
 * Contributor(s): ______________________________________.
 
18
 * Changes made by Claudio Valderrama for the Firebird project 
 
19
 *   changes to substr and added substrlen 
 
20
 * 2004.9.1 Claudio Valderrama, change some UDF's to be able to detect NULL.
 
21
 * 2004.12.5 Slavomir Skopalik contributed IB_UDF_frac.
 
22
 * 
 
23
 */
 
24
 
 
25
#include "firebird.h"
 
26
#include <math.h>
 
27
#include <stdlib.h>
 
28
#include <string.h>
 
29
#if TIME_WITH_SYS_TIME
 
30
# include <sys/time.h>
 
31
# include <time.h>
 
32
#else
 
33
# if HAVE_SYS_TIME_H
 
34
#  include <sys/time.h>
 
35
# else
 
36
#  include <time.h>
 
37
# endif
 
38
#endif
 
39
#include "fb_types.h"
 
40
#include "ib_util.h"
 
41
#include "ib_udf.h"
 
42
 
 
43
extern "C"
 
44
{
 
45
 
 
46
#ifndef SOLARIS
 
47
#ifdef WIN_NT
 
48
#define exception_type _exception
 
49
#else
 
50
#define exception_type __exception
 
51
#endif
 
52
int MATHERR(struct exception_type *e)
 
53
{
 
54
        return 1;
 
55
}
 
56
#undef exception_type
 
57
#endif /* SOLARIS */
 
58
 
 
59
double EXPORT IB_UDF_abs( double *a)
 
60
{
 
61
        return (*a < 0.0) ? -*a : *a;
 
62
}
 
63
 
 
64
double EXPORT IB_UDF_acos( double *a)
 
65
{
 
66
        return (acos(*a));
 
67
}
 
68
 
 
69
char *EXPORT IB_UDF_ascii_char( ISC_LONG *a)
 
70
{
 
71
        if (!a)
 
72
                return 0;
 
73
 
 
74
        char* b = (char *) ib_util_malloc(2);
 
75
        *b = (char) (*a);
 
76
        /* let us not forget to NULL terminate */
 
77
        b[1] = '\0';
 
78
        return (b);
 
79
}
 
80
 
 
81
ISC_LONG EXPORT IB_UDF_ascii_val( const char *a)
 
82
{
 
83
        // NULL is treated as ASCII(0).
 
84
        return ((ISC_LONG) (*a));
 
85
}
 
86
 
 
87
double EXPORT IB_UDF_asin( double *a)
 
88
{
 
89
        return (asin(*a));
 
90
}
 
91
 
 
92
double EXPORT IB_UDF_atan( double *a)
 
93
{
 
94
        return (atan(*a));
 
95
}
 
96
 
 
97
double EXPORT IB_UDF_atan2( double *a, double *b)
 
98
{
 
99
        return (atan2(*a, *b));
 
100
}
 
101
 
 
102
ISC_LONG EXPORT IB_UDF_bin_and( ISC_LONG *a, ISC_LONG *b)
 
103
{
 
104
        return (*a & *b);
 
105
}
 
106
 
 
107
ISC_LONG EXPORT IB_UDF_bin_or( ISC_LONG *a, ISC_LONG *b)
 
108
{
 
109
        return (*a | *b);
 
110
}
 
111
 
 
112
ISC_LONG EXPORT IB_UDF_bin_xor( ISC_LONG *a, ISC_LONG *b)
 
113
{
 
114
        return (*a ^ *b);
 
115
}
 
116
 
 
117
double EXPORT IB_UDF_ceiling( double *a)
 
118
{
 
119
        return (ceil(*a));
 
120
}
 
121
 
 
122
double EXPORT IB_UDF_cos( double *a)
 
123
{
 
124
        return (cos(*a));
 
125
}
 
126
 
 
127
double EXPORT IB_UDF_cosh( double *a)
 
128
{
 
129
        return (cosh(*a));
 
130
}
 
131
 
 
132
double EXPORT IB_UDF_cot( double *a)
 
133
{
 
134
        return (1.0 / tan(*a));
 
135
}
 
136
 
 
137
double EXPORT IB_UDF_div( ISC_LONG *a, ISC_LONG *b)
 
138
{
 
139
        if (*b != 0)
 
140
        {
 
141
                // VS8.0 has two implementations of div().
 
142
                // Let's explicitly use the int-aware one.
 
143
                div_t div_result = div((int) *a, (int) *b);
 
144
                return (div_result.quot);
 
145
        }
 
146
        else
 
147
        {
 
148
                // This is a Kludge!  We need to return INF, 
 
149
                // but this seems to be the only way to do 
 
150
                // it since there seens to be no constant for it.
 
151
#ifdef HAVE_INFINITY
 
152
                return INFINITY;
 
153
#else
 
154
                return (1 / tan(0.0));
 
155
#endif
 
156
        }
 
157
}
 
158
 
 
159
double EXPORT IB_UDF_floor( double *a)
 
160
{
 
161
        return (floor(*a));
 
162
}
 
163
 
 
164
double EXPORT IB_UDF_frac(const double* x)
 
165
{
 
166
        if (*x > 0)
 
167
                return *x - floor(*x);
 
168
        if (*x < 0)
 
169
                return *x - ceil(*x);
 
170
        return 0;
 
171
}
 
172
 
 
173
double EXPORT IB_UDF_ln( double *a)
 
174
{
 
175
        return (log(*a));
 
176
}
 
177
 
 
178
double EXPORT IB_UDF_log( double *a, double *b)
 
179
{
 
180
        return (log(*b) / log(*a));
 
181
}
 
182
 
 
183
double EXPORT IB_UDF_log10( double *a)
 
184
{
 
185
        return (log10(*a));
 
186
}
 
187
 
 
188
char *EXPORT IB_UDF_lower(const char *s)
 
189
{
 
190
        if (!s)
 
191
                return 0;
 
192
                
 
193
        char* buf = (char *) ib_util_malloc(strlen(s) + 1);
 
194
        char* p = buf;
 
195
        while (*s)
 
196
        {
 
197
                if (*s >= 'A' && *s <= 'Z') {
 
198
                        *p++ = *s++ - 'A' + 'a';
 
199
                }
 
200
                else
 
201
                        *p++ = *s++;
 
202
        }
 
203
        *p = '\0';
 
204
 
 
205
        return buf;
 
206
}
 
207
 
 
208
char *EXPORT IB_UDF_lpad( const char *s, ISC_LONG *a, const char *c)
 
209
{
 
210
        if (!s || !c)
 
211
                return 0;
 
212
 
 
213
        const long avalue = *a;
 
214
        
 
215
        if (avalue >= 0) {
 
216
                long current = 0;
 
217
                const long length = strlen(s);
 
218
                const long padlength = strlen(c);
 
219
                const long stop = avalue < length ? avalue : length;
 
220
                char* buf = (char*) ib_util_malloc(avalue + 1);
 
221
 
 
222
                if (padlength)
 
223
                {
 
224
                        while (current + length < avalue) {
 
225
                                memcpy(&buf[current], c, padlength);
 
226
                                current += padlength;
 
227
                        }
 
228
                        memcpy(&buf[(avalue - length < 0) ? 0 : avalue - length], s, stop);
 
229
                        buf[avalue] = '\0';
 
230
                }
 
231
                else {
 
232
                        memcpy(buf, s, stop);
 
233
                        buf[stop] = '\0';
 
234
                }
 
235
                return buf;
 
236
        }
 
237
        else
 
238
                return NULL;
 
239
}
 
240
 
 
241
char *EXPORT IB_UDF_ltrim( const char *s)
 
242
{
 
243
        if (!s)
 
244
                return 0;
 
245
                
 
246
        while (*s == ' ')               /* skip leading blanks */
 
247
                s++;
 
248
                
 
249
        const long length = strlen(s);
 
250
        char* buf = (char *) ib_util_malloc(length + 1);
 
251
        memcpy(buf, s, length);
 
252
        buf[length] = '\0';
 
253
 
 
254
        return buf;
 
255
}
 
256
 
 
257
double EXPORT IB_UDF_mod( ISC_LONG *a, ISC_LONG *b)
 
258
{
 
259
        if (*b != 0)
 
260
        {
 
261
                // VS8.0 has two implementations of div().
 
262
                // Let's explicitly use the int-aware one.
 
263
                div_t div_result = div((int) *a, (int) *b);
 
264
                return (div_result.rem);
 
265
        }
 
266
        else
 
267
        {
 
268
                // This is a Kludge!  We need to return INF, 
 
269
                // but this seems to be the only way to do 
 
270
                // it since there seens to be no constant for it.
 
271
#ifdef HAVE_INFINITY
 
272
                return INFINITY;
 
273
#else
 
274
                return (1 / tan(0.0));
 
275
#endif
 
276
        }
 
277
}
 
278
 
 
279
double EXPORT IB_UDF_pi()
 
280
{
 
281
        return (IB_PI);
 
282
}
 
283
 
 
284
double EXPORT IB_UDF_srand()
 
285
{
 
286
        srand((unsigned) time(NULL));
 
287
        return ((float) rand() / (float) RAND_MAX);
 
288
}
 
289
 
 
290
double EXPORT IB_UDF_rand()
 
291
{
 
292
        return ((float) rand() / (float) RAND_MAX);
 
293
}
 
294
 
 
295
char *EXPORT IB_UDF_rpad( const char *s, ISC_LONG *a, const char *c)
 
296
{
 
297
        if (!s || !c)
 
298
                return 0;
 
299
                
 
300
        const long avalue = *a;
 
301
 
 
302
        if (avalue >= 0) {
 
303
                const long length = strlen(s);
 
304
                long current = (avalue - length) < 0 ? avalue : length;
 
305
                const long padlength = strlen(c);
 
306
                char* buf = (char*) ib_util_malloc (avalue + 1);
 
307
                memcpy(buf, s, current);
 
308
 
 
309
                if (padlength)
 
310
                {
 
311
                        while (current + padlength < avalue) {
 
312
                                memcpy(&buf[current], c, padlength);
 
313
                                current += padlength;
 
314
                        }
 
315
                        memcpy(&buf[current], c, avalue - current);
 
316
                        buf[avalue] = '\0';
 
317
                }
 
318
                else
 
319
                        buf[current] = 0;
 
320
 
 
321
                return buf;
 
322
        }
 
323
        else
 
324
                return NULL;
 
325
}
 
326
 
 
327
char *EXPORT IB_UDF_rtrim( const char *s)
 
328
{
 
329
        if (!s)
 
330
                return 0;
 
331
                
 
332
        const char* p = s + strlen(s);
 
333
        while (--p >= s && *p == ' '); // empty loop body
 
334
        
 
335
        const long length = p - s + 1;
 
336
        char* buf = (char *) ib_util_malloc(length + 1);
 
337
        memcpy(buf, s, length);
 
338
        buf[length] = '\0';
 
339
 
 
340
        return buf;
 
341
}
 
342
 
 
343
ISC_LONG EXPORT IB_UDF_sign( double *a)
 
344
{
 
345
        if (*a > 0)
 
346
                return 1;
 
347
        if (*a < 0)
 
348
                return -1;
 
349
        /* If neither is true then it equals 0 */
 
350
        return 0;
 
351
}
 
352
 
 
353
double EXPORT IB_UDF_sin( double *a)
 
354
{
 
355
        return (sin(*a));
 
356
}
 
357
 
 
358
double EXPORT IB_UDF_sinh( double *a)
 
359
{
 
360
        return (sinh(*a));
 
361
}
 
362
 
 
363
double EXPORT IB_UDF_sqrt( double *a)
 
364
{
 
365
        return (sqrt(*a));
 
366
}
 
367
 
 
368
char* EXPORT IB_UDF_substr(const char* s, ISC_SHORT* m, ISC_SHORT* n)
 
369
{
 
370
        if (!s) {
 
371
                return 0;
 
372
        }
 
373
 
 
374
        char* buf;
 
375
        long length = strlen(s);
 
376
        if (!length ||
 
377
                *m > *n ||
 
378
                *m < 1  ||
 
379
                *n < 1  ||
 
380
                *m > length)
 
381
        {
 
382
                buf = (char*)ib_util_malloc(1);
 
383
                buf[0] = '\0';
 
384
        }
 
385
        else
 
386
        {
 
387
                /* we want from the mth char to the
 
388
                   nth char inclusive, so add one to
 
389
                   the length. */
 
390
                /* CVC: We need to compensate for n if it's longer than s's length */
 
391
                if (*n > length) {
 
392
                        length -= *m - 1;
 
393
                }
 
394
                else {
 
395
                        length = *n - *m + 1;
 
396
                }
 
397
                buf = (char*)ib_util_malloc (length + 1);
 
398
                memcpy(buf, s + *m - 1, length);
 
399
                buf[length] = '\0';
 
400
        }
 
401
        return buf;
 
402
}
 
403
 
 
404
char* EXPORT IB_UDF_substrlen(const char* s, ISC_SHORT* m, ISC_SHORT* n)
 
405
{
 
406
        /* Created by Claudio Valderrama for the Firebird project,
 
407
                2001.04.17 We don't want to return NULL when params are wrong
 
408
                and we'll return the remaining characters if the final position
 
409
                is greater than the string's length, unless NULL is provided.
 
410
        */
 
411
        if (!s) {
 
412
                return NULL;
 
413
        }
 
414
 
 
415
        char* buf;
 
416
        long length = strlen(s);
 
417
        if (!length ||
 
418
                *m < 1  ||
 
419
                *n < 1  ||
 
420
                *m > length)
 
421
        {
 
422
                buf = (char*)ib_util_malloc(1);
 
423
                buf[0] = '\0';
 
424
        }
 
425
        else {
 
426
                /* we want from the mth char to the (m+n)th char inclusive,
 
427
                 * so add one to the length.
 
428
                 */
 
429
                /* CVC: We need to compensate for n if it's longer than s's length */
 
430
                if (*m + *n - 1 > length) {
 
431
                        length -= *m - 1;
 
432
                }
 
433
                else {
 
434
                        length = *n;
 
435
                }
 
436
                buf = (char*) ib_util_malloc (length + 1);
 
437
                memcpy(buf, s + *m - 1, length);
 
438
                buf[length] = '\0';
 
439
        }
 
440
        return buf;
 
441
}
 
442
 
 
443
ISC_LONG EXPORT IB_UDF_strlen( const char *a)
 
444
{
 
445
        return (strlen(a));
 
446
}
 
447
 
 
448
double EXPORT IB_UDF_tan( double *a)
 
449
{
 
450
        return (tan(*a));
 
451
}
 
452
 
 
453
double EXPORT IB_UDF_tanh( double *a)
 
454
{
 
455
        return (tanh(*a));
 
456
}
 
457
 
 
458
} // extern "C"
 
459