home *** CD-ROM | disk | FTP | other *** search
- /*====================================================================
- 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;
- }
-
-