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
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.
12
* The Original Code was created by Inprise Corporation
13
* and its predecessors. Portions created by Inprise Corporation are
14
* Copyright (C) Inprise Corporation.
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.
29
#if TIME_WITH_SYS_TIME
30
# include <sys/time.h>
34
# include <sys/time.h>
48
#define exception_type _exception
50
#define exception_type __exception
52
int MATHERR(struct exception_type *e)
59
double EXPORT IB_UDF_abs( double *a)
61
return (*a < 0.0) ? -*a : *a;
64
double EXPORT IB_UDF_acos( double *a)
69
char *EXPORT IB_UDF_ascii_char( ISC_LONG *a)
74
char* b = (char *) ib_util_malloc(2);
76
/* let us not forget to NULL terminate */
81
ISC_LONG EXPORT IB_UDF_ascii_val( const char *a)
83
// NULL is treated as ASCII(0).
84
return ((ISC_LONG) (*a));
87
double EXPORT IB_UDF_asin( double *a)
92
double EXPORT IB_UDF_atan( double *a)
97
double EXPORT IB_UDF_atan2( double *a, double *b)
99
return (atan2(*a, *b));
102
ISC_LONG EXPORT IB_UDF_bin_and( ISC_LONG *a, ISC_LONG *b)
107
ISC_LONG EXPORT IB_UDF_bin_or( ISC_LONG *a, ISC_LONG *b)
112
ISC_LONG EXPORT IB_UDF_bin_xor( ISC_LONG *a, ISC_LONG *b)
117
double EXPORT IB_UDF_ceiling( double *a)
122
double EXPORT IB_UDF_cos( double *a)
127
double EXPORT IB_UDF_cosh( double *a)
132
double EXPORT IB_UDF_cot( double *a)
134
return (1.0 / tan(*a));
137
double EXPORT IB_UDF_div( ISC_LONG *a, ISC_LONG *b)
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);
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.
154
return (1 / tan(0.0));
159
double EXPORT IB_UDF_floor( double *a)
164
double EXPORT IB_UDF_frac(const double* x)
167
return *x - floor(*x);
169
return *x - ceil(*x);
173
double EXPORT IB_UDF_ln( double *a)
178
double EXPORT IB_UDF_log( double *a, double *b)
180
return (log(*b) / log(*a));
183
double EXPORT IB_UDF_log10( double *a)
188
char *EXPORT IB_UDF_lower(const char *s)
193
char* buf = (char *) ib_util_malloc(strlen(s) + 1);
197
if (*s >= 'A' && *s <= 'Z') {
198
*p++ = *s++ - 'A' + 'a';
208
char *EXPORT IB_UDF_lpad( const char *s, ISC_LONG *a, const char *c)
213
const long avalue = *a;
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);
224
while (current + length < avalue) {
225
memcpy(&buf[current], c, padlength);
226
current += padlength;
228
memcpy(&buf[(avalue - length < 0) ? 0 : avalue - length], s, stop);
232
memcpy(buf, s, stop);
241
char *EXPORT IB_UDF_ltrim( const char *s)
246
while (*s == ' ') /* skip leading blanks */
249
const long length = strlen(s);
250
char* buf = (char *) ib_util_malloc(length + 1);
251
memcpy(buf, s, length);
257
double EXPORT IB_UDF_mod( ISC_LONG *a, ISC_LONG *b)
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);
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.
274
return (1 / tan(0.0));
279
double EXPORT IB_UDF_pi()
284
double EXPORT IB_UDF_srand()
286
srand((unsigned) time(NULL));
287
return ((float) rand() / (float) RAND_MAX);
290
double EXPORT IB_UDF_rand()
292
return ((float) rand() / (float) RAND_MAX);
295
char *EXPORT IB_UDF_rpad( const char *s, ISC_LONG *a, const char *c)
300
const long avalue = *a;
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);
311
while (current + padlength < avalue) {
312
memcpy(&buf[current], c, padlength);
313
current += padlength;
315
memcpy(&buf[current], c, avalue - current);
327
char *EXPORT IB_UDF_rtrim( const char *s)
332
const char* p = s + strlen(s);
333
while (--p >= s && *p == ' '); // empty loop body
335
const long length = p - s + 1;
336
char* buf = (char *) ib_util_malloc(length + 1);
337
memcpy(buf, s, length);
343
ISC_LONG EXPORT IB_UDF_sign( double *a)
349
/* If neither is true then it equals 0 */
353
double EXPORT IB_UDF_sin( double *a)
358
double EXPORT IB_UDF_sinh( double *a)
363
double EXPORT IB_UDF_sqrt( double *a)
368
char* EXPORT IB_UDF_substr(const char* s, ISC_SHORT* m, ISC_SHORT* n)
375
long length = strlen(s);
382
buf = (char*)ib_util_malloc(1);
387
/* we want from the mth char to the
388
nth char inclusive, so add one to
390
/* CVC: We need to compensate for n if it's longer than s's length */
395
length = *n - *m + 1;
397
buf = (char*)ib_util_malloc (length + 1);
398
memcpy(buf, s + *m - 1, length);
404
char* EXPORT IB_UDF_substrlen(const char* s, ISC_SHORT* m, ISC_SHORT* n)
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.
416
long length = strlen(s);
422
buf = (char*)ib_util_malloc(1);
426
/* we want from the mth char to the (m+n)th char inclusive,
427
* so add one to the length.
429
/* CVC: We need to compensate for n if it's longer than s's length */
430
if (*m + *n - 1 > length) {
436
buf = (char*) ib_util_malloc (length + 1);
437
memcpy(buf, s + *m - 1, length);
443
ISC_LONG EXPORT IB_UDF_strlen( const char *a)
448
double EXPORT IB_UDF_tan( double *a)
453
double EXPORT IB_UDF_tanh( double *a)