home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 1999 May
/
PCWorld_1999-05_cd.bin
/
software
/
Vyzkuste
/
inprise
/
INTRBASE_55
/
EXAMPLES
/
API
/
UDFLIB.C
< prev
next >
Wrap
C/C++ Source or Header
|
1998-10-18
|
12KB
|
466 lines
/*====================================================================
File Name: udflib.c
Description:
This module contains some user defined functions (UDF).
The test suite for UDF will use udf.sql
to define UDF to the database using SQL statements.
====================================================================== */
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <math.h>
#include <ibase.h>
#include "example.h"
#define BADVAL -9999L
#define MYBUF_LEN 15 /* number of chars to get for */
typedef struct blob {
short (*blob_get_segment) ();
void *blob_handle;
long blob_number_segments;
long blob_max_segment;
long blob_total_length;
void (*blob_put_segment) ();
} *BLOB;
time_t time();
char *ctime();
/* variable to return values in. Needs to be static so it doesn't go
away as soon as the function invocation is finished */
char buffer[256];
char buffer2[512]; /* for string concatenation */
char datebuf[12]; /* for date string */
long r_long;
double r_double;
float r_float;
short r_short;
struct tm *tbuf;
long time_sec;
ISC_QUAD newdate;
/*===============================================================
fn_lower_c() - Puts its argument longo lower case, for C programs
Input is of VARCHAR, output is of CSTRING.
Not international or non-ascii friendly.
================================================================= */
char* EXPORT fn_lower_c (ARG(char*, s))
ARGLIST(char *s) /* VARCHAR input */
{
char *buf;
short length = 0;
char *buffer = (char *)malloc(256);
length = (short)*s;
s += 2;
buf = buffer;
while (*s)
if (*s >= 'A' && *s <= 'Z')
*buf++ = *s++ - 'A' + 'a';
else
*buf++ = *s++;
*buf = '\0';
buffer [length] = '\0';
return buffer;
}
/*===============================================================
fn_strcat(s1, s2) - Returns concatenated string.
s1 and s2 are varchar to get a length count
================================================================= */
char* EXPORT fn_strcat(ARG(char*, s1), ARG(char*, s2))
ARGLIST(char *s1)
ARGLIST(char *s2)
{
short j = 0;
short length1, length2;
char *p;
char *buffer2 = (char *)malloc(512);
length1 = (short)*s1;
length2 = (short)*s2;
s1 += 2;
s2 += 2;
/* strip trailing blanks of s1 */
p = s1 + length1 - 1;
while (*p && *p == ' ')
p--;
p++;
*p = '\0';
p = buffer2;
while (*s1)
*p++ = *s1++;
for (j = 0; j < length2; j++)
if (*s2)
*p++ = *s2++;
*p = '\0';
return buffer2;
}
/*===============================================================
fn_substr(s, m, n) - Returns the substr starting m ending n in s.
================================================================= */
char* EXPORT fn_substr(ARG(char*, s), ARG(short*, m), ARG(short*, n))
ARGLIST(char *s)
ARGLIST(short *m) /* starting position */
ARGLIST(short *n) /* ending position */
{
short i = 0;
short j = 0;
char *buffer = (char *)malloc(256);
if (*m > *n || *m < 1 || *n < 1) return "Bad parameters in substring";
while (*s && i++ < *m-1) /* skip */
s++;
while (*s && i++ <= *n) /* copy */
buffer[j++] = *s++;
buffer[j] = '\0';
return buffer;
}
/*===============================================================
fn_trim(s) - Returns string that has leading blanks trimmed.
================================================================= */
char* EXPORT fn_trim(ARG(char*, s))
ARGLIST(char *s)
{
short j = 0;
char *buffer = (char *)malloc(256);
while (*s == ' ') /* skip leading blanks */
s++;
while (*s) /* copy the rest */
buffer[j++] = *s++;
buffer[j] = '\0';
return buffer;
}
/*===============================================================
fn_trunc(s, m) - Returns the string truncated at position m;
Input is of CSTRING, output is of VARCHAR.
================================================================= */
char* EXPORT fn_trunc(ARG(char*, s), ARG(short*, m))
ARGLIST(char *s)
ARGLIST(short *m)
{
short j = 2; /* leave 1st 2 bytes for VARCHAR output */
char *buffer = (char *)malloc(256);
while (*s && j < *m + 2) /* need to add 2 */
buffer[j++] = *s++;
buffer[j] = '\0';
buffer[0] = (unsigned short) strlen(s) + 2;
buffer[1] = ' '; /* anything other than \0 */
/*
*((unsigned short *)buffer) = (unsigned short) (strlen(buffer) + 2);
*/
return buffer; /* VARCHAR output */
}
/* ==============================================================
fn_doy() return the nth day of the year, by value.
============================================================== */
long EXPORT fn_doy()
{
char buf[4]; /* for day */
long i;
time (&time_sec);
tbuf = localtime(&time_sec);
i = strftime(buf, 4, "%j", tbuf);
return atoi (buf);
}
/* ==============================================================
fn_moy() return the nth month of the year. e.g. 1,2,3,...12.
Return by reference.
============================================================== */
short* EXPORT fn_moy()
{
time (&time_sec);
tbuf = localtime(&time_sec);
r_short = (short) tbuf->tm_mon + 1;
return &r_short;
}
/* ==============================================================
fn_dow() return the day of today. e.g., Monday, Friday. ...
============================================================== */
char* EXPORT fn_dow()
{
time (&time_sec);
tbuf = localtime(&time_sec);
switch (tbuf->tm_wday) {
case 1: return "Monday";
case 2: return "Tuesday";
case 3: return "Wednesday";
case 4: return "Thursday";
case 5: return "Friday";
case 6: return "Saturday";
case 7: return "Sunday";
default: return "Error in Date";
}
}
/*===============================================================
fn_sysdate() - Returns the system date in the "MMM-DD-YYYY" format.
================================================================= */
char* EXPORT fn_sysdate()
{
short len, i, j = 0;
char *time_str;
char *datebuf = (char *)malloc(12);
time (&time_sec);
time_str = ctime (&time_sec);
len = strlen(time_str);
for (i = 4; i <= 10; i++) {
if (*(time_str + i) != ' ')
datebuf[j++] = *(time_str+i);
else if (i == 7 || i == 10)
datebuf[j++] = '-';
else
datebuf[j++] = '0';
}
for (i = 20; i < len-1 ; i++)
datebuf[j++] = *(time_str+i);
datebuf[j] = '\0';
return datebuf;
}
/* ==============================================
fn_add2 (a, b) - returns a + b
=============================================== */
long EXPORT fn_add2 (ARG(long*, a), ARG(long*, b))
ARGLIST(long *a)
ARGLIST(long *b)
{
return (*a + *b);
}
/* ==================================================
fn_mul (a, b) - returns a * b
=================================================== */
double EXPORT fn_mul (ARG(double*, a), ARG(double*, b))
ARGLIST(double *a)
ARGLIST(double *b)
{
return (*a * *b);
}
/* ==============================================
fn_fact (n) - return factorial of n
================================================ */
double EXPORT fn_fact (ARG(double*, n))
ARGLIST(double *n)
{
double k;
if (*n > 100) return BADVAL;
if (*n < 0) return BADVAL;
if (*n == 0) return 1L;
else {
k = *n - 1L;
return (*n * fn_fact(&k));
}
}
/*===============================================================
fn_abs() - returns the absolute value of its argument.
================================================================= */
double EXPORT fn_abs(ARG(double*, x))
ARGLIST(double *x)
{
return (*x < 0.0) ? -*x : *x;
}
/*===============================================================
fn_max() - Returns the greater of its two arguments
================================================================ */
double EXPORT fn_max(ARG(double*, a), ARG(double*, b))
ARGLIST(double *a)
ARGLIST(double *b)
{
return (*a > *b) ? *a : *b;
}
/*===============================================================
fn_sqrt() - Returns square root of n
================================================================ */
double* EXPORT fn_sqrt(ARG(double*, n))
ARGLIST(double *n)
{
r_double = sqrt(*n);
return &r_double;
}
/*=============================================================
fn_blob_linecount() returns the number of lines in a blob
=============================================================*/
long EXPORT fn_blob_linecount (ARG(BLOB, b))
ARGLIST(BLOB b)
{
char *buf, *p;
short length, actual_length;
/* Null values */
if (!b->blob_handle)
return 0L;
length = b->blob_max_segment + 1L;
buf = (char *) malloc (length);
r_long = 0;
while ((*b->blob_get_segment) (b->blob_handle, buf, length, &actual_length))
{
buf [actual_length] = 0;
p = buf;
while (*p)
if (*p++ == '\n')
r_long++;
}
free (buf);
return r_long;
}
/*=============================================================
fn_blob_bytecount() returns the number of bytes in a blob
do not count newlines, so get rid of the newlines.
==============================================================*/
long EXPORT fn_blob_bytecount (ARG(BLOB, b))
ARGLIST(BLOB b)
{
/* Null values */
if (!b->blob_handle)
return 0L;
return (b->blob_total_length - fn_blob_linecount(b));
}
/*=============================================================
fn_substr_blob() returns portion of TEXT blob beginning at m th
character and ended at n th character.
Newlines are eliminated to make for better printing.
=============================================================*/
char* EXPORT fn_blob_substr(ARG(BLOB, b), ARG(long*, m), ARG(long*, n))
ARGLIST(BLOB b)
ARGLIST(long *m)
ARGLIST(long *n)
{
char *buf, *p, *q;
long i = 0;
long curr_bytecount = 0;
long begin, end;
short length, actual_length;
char *buffer = (char *)malloc(256);
if (!b->blob_handle)
return "<null>";
length = b->blob_max_segment + 1L;
buf = (char *) malloc (length);
if (*m > *n || *m < 1L || *n < 1L)
return "";
if (b->blob_total_length < (long)*m)
return "";
begin = *m; /* beginning position */
if (b->blob_total_length < (long)*n)
end = b->blob_total_length; /* ending position */
else
end = *n;
/* Limit the return string to 255 bytes */
if (end - begin + 1L > 255L)
end = begin + 254L;
q = buffer;
while ((*b->blob_get_segment) (b->blob_handle, buf, length,
&actual_length))
{
buf [actual_length] = 0;
p = buf;
while (*p && (curr_bytecount <= end))
{
curr_bytecount++;
if (*p == '\n')
*p = ' ';
if (curr_bytecount >= begin)
*q++ = *p;
p++;
}
if (curr_bytecount >= end)
{
*q = 0;
break;
}
}
free (buf);
return buffer;
}