The following example uses a UDF named dwrd to convert a currency value to words:
SET VAR v1=(UDF('dwrd','$1,456.99'))
If you execute the above command and then enter SHOW VARIABLE at the R> Prompt, you see the following output:
one thousand four hundred fifty-six dollars and ninety-nine cents
Examples
The following is a R:BASE command that calls the UDF named random.
SET VAR v1 = (UDF('random', '25 345'))
The following are the command line arguments for the UDF named random for DOS as seen by the UDF code:
DOS
argv[0] = random
argv[1] = 25
argv[2] = 345
argv[3] = A345BD3456
argc = 4
Argument 0 is the name of the executable. Argument 1 is the first parameter. Argument 2 is the second parameter. Argument 3 is the memory address. This brings the argument count to 4.
The following example uses a UDF named DWRD.EXE to convert a currency value to words:
SET VAR v1=(UDF('dwrd','$1,456.99'))
SHOW VAR v1
Result: v1= one thousand, four hundred fifty six dollars and ninety nine cents
The following example uses the DWRD.DLL to accomplish the same function.
SET VAR v1=(UDF('@dwrd.dll','$1,456.99'))
SHOW VAR v1
Result: v1= one thousand, four hundred fifty six dollars and ninety nine cents
Source Code
What follows is the source code for the dwrd.exe sample UDF, shipped with DOS products, and the source code for the dwrd.dll sample UDF, shipped with Windows products.
/*
* Copyright 2001 by R:BASE Technologies, Inc.
* Author: Wayne J. Erickson 12 Apr 1991
*
************************************************************************
* * Routine: dwrd2 *** DOS VERSION ***
* * Purpose: convert a currency value to words
*
* Input Parameters:
* name Brief description
* -------------- ------------------------------------------------
* value Currency string to be parsed
* Shared Segment Shared memory segment to place the parsed string
*
************************************************************************
*/
#include
#include
#include
void conout(char *, int);
void crlf(void);
int lenstr(char *, int);
void dwrd(char *, char *);
cdecl main(argc,argv)
int argc;
char * argv[];
{
long int i4;
char *pt;
char wordnum[160];
int lw;
/* Get the argument count. */
if(argc <= 1) {
conout("DWRD number pointer", 19);
crlf();
goto done;
}
/* Do the conversion */
dwrd(argv[1], wordnum);
/* Display the result */
lw = strlen(wordnum);
if (argc == 2) {
conout(wordnum, lw);
crlf();
}
/* See if there was an address to store the result */
if(argc > 2) {
i4 = atol(argv[2]);
pt = (char *)i4;
memcpy(pt, wordnum, lw+1);
}
done:
return(0);
}
/**** Start of DWRD function ****/
void dwrd(strin, strout)
char *strin;
char *strout;
{
int lstr;
static char numbers[20][10] = {
" ","one ","two ",
"three ","four ","five ",
"six ","seven ","eight ",
"nine ","ten ","eleven ",
"twelve ","thirteen ","fourteen ",
"fifteen ","sixteen ","seventeen ",
"eighteen ","nineteen "};
static char tenvals[10][10] = {
"no ","ten ","twenty ",
"thirty ","forty ","fifty ",
"sixty ","seventy ","eighty ",
"ninety "};
char blank = ' ';
char comma = ',';
char dsign = '$';
char dot = '.';
char minus = '-';
char ch;
char tmoney[16];
int offset;
int tens;
int lw, ls, n, intch, l;
/* CONVERT THE NUMBER. */
tens = 0;
memset(tmoney, ' ', 16);
lw = 0;
lstr = strlen(strin);
ls = 16 - lstr + 1;
strcpy(&tmoney[ls-1],strin);
/* PICK OFF THE CHARACTERS. */
n = ls - 1;
next_digit:
n++;
if(n > 16) goto cleanup;
ch = tmoney[n-1];
/* SKIP THE COSMETIC CHARACTERS. */
if((ch == blank) || (ch == comma) || (ch == dsign)) goto next_digit;
if(ch == minus) {
memcpy(&strout[(lw+1)-1], "minus ", 6);
lw = lw + 6;
goto next_digit;
}
if((n == 4) || (n == 8) || (n == 12)) tens = 1;
/* SPECIAL STUFF WHEN WE HIT THE DECIMAL POINT. */
if(ch == dot) {
tens = 1;
if(lw == 0) {
memcpy(&strout[(lw+1)-1], "zero ", 5);
lw = lw + 5;
}
memcpy(&strout[(lw+1)-1], "dollars and ", 12);
lw = lw + 12;
if(tmoney[(n+1)-1] == '0') {
if(tmoney[(n+2)-1] == '0') {
memcpy(&strout[(lw+1)-1], "zero ", 5);
lw = lw + 5;
n = n + 2;
}
}
goto next_digit;
}
/* CONVERT A CHARACTER INTO AN OFFSET. */
intch = ch - 48;
if(tens) {
if(intch <= 1) {
offset = 0;
if(intch == 1) offset = 10;
n = n + 1;
ch = tmoney[(n)-1];
intch = ch - 48 + offset;
}
else {
l = lenstr(tenvals[(intch+1) - 1], 10);
if(l > 0) {
memcpy(&strout[(lw+1)-1], tenvals[(intch+1)-1], l+1);
lw = lw + l + 1;
}
tens = 0;
goto next_digit;
}
}
l = lenstr(numbers[(intch+1)-1], 10);
if(l > 0) {
memcpy(&strout[(lw+1)-1], numbers[(intch+1)-1], l+1);
lw = lw + l + 1;
}
tens = 0;
if(((n == 3) || (n == 7) || (n == 11)) && (intch != 0)) {
memcpy(&strout[(lw+1)-1], "hundred ", 8);
lw = lw + 8;
}
if(n == 5) {
memcpy(&strout[(lw+1)-1], "million ", 8);
lw = lw + 8;
}
if(n == 9) {
memcpy(&strout[(lw+1)-1], "thousand ", 9);
lw = lw + 9;
}
goto next_digit;
cleanup:
memcpy(&strout[(lw+1)-1], "cents", 5);
lw = lw + 5;
/* Add the null terminator */
strout[(lw+1)-1] = '\0';
/* ALL DONE. */
return;
}
/**** End of DWRD function ****/
/**** Start of CONOUT function ****/
void conout(str, count)
char *str;
int count;
{
int i;
for (i = 0; i < count; i++) {
putchar(str[i]);
}
return;
}
/**** End of CONOUT function ****/
/**** Start of CRLF function ****/
void crlf()
{
putchar('\r');
putchar('\n');
return;
}
/**** End of CRLF function ****/
/**** Start of LENSTR function ****/
int lenstr(str, count)
char *str;
int count;
{
int i;
i = count - 1;
while (i >= 0) {
if (str[i] != ' ') break;
i--;
}
return (i+1);
}
/**** End of LENSTR function ****/
#include
/*
* Copyright 2001 R:BASE Technologies, Inc.
* Author: Wayne J. Erickson 18 October 1999
*
************************************************************************
*
* Routine: dwrd *** DLL VERSION ***
*
* Purpose: convert a currency value to words
*
* Input Parameters:
* name Brief description
* -------------- ------------------------------------------------
* value Currency string to be parsed
* Shared Segment Shared memory segment to place the parsed string
*
*
************************************************************************
*/
#include
void dwrd(char *, char *);
int lenstr(char *, int);
#pragma hdrstop
//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
return 1;
}
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport) int WINAPI RbDllExec(const HWND dc,const char *in, int inlen, char *out, int outlen)
{
int returnValue = 0;
char instr[80];
char wordnum[160];
// Put the input string in a null terminated string
memcpy(instr, in, inlen);
instr[inlen] = '\0';
// Convert to a text string
dwrd(instr, wordnum);
// Return the result
outlen = strlen(wordnum);
if (outlen)
memcpy(out, wordnum, outlen);
// returnValue = MessageBox(dc, wordnum,"Result value",MB_OK);
// returnValue = 0;
return returnValue;
}
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport) int WINAPI RbDllVersion(void)
{
return 100;
}
/**** Start of DWRD function ****/
void dwrd(char *strin,char *strout)
{
int lstr;
static char numbers[20][11] = {
" ","one ","two ",
"three ","four ","five ",
"six ","seven ","eight ",
"nine ","ten ","eleven ",
"twelve ","thirteen ","fourteen ",
"fifteen ","sixteen ","seventeen ",
"eighteen ","nineteen "};
static char tenvals[10][11] = {
"no ","ten ","twenty ",
"thirty ","forty ","fifty ",
"sixty ","seventy ","eighty ",
"ninety "};
char blank = ' ';
char comma = ',';
char dsign = '$';
char dot = '.';
char minus = '-';
char ch;
char tmoney[16];
int offset;
int tens;
int lw, ls, n, intch, l;
/* CONVERT THE NUMBER. */
tens = 0;
memset(tmoney, ' ', 16);
lw = 0;
lstr = strlen(strin);
ls = 16 - lstr + 1;
strcpy(&tmoney[ls-1],strin);
/* PICK OFF THE CHARACTERS. */
n = ls - 1;
next_digit:
n++;
if(n > 16) goto cleanup;
ch = tmoney[n-1];
/* SKIP THE COSMETIC CHARACTERS. */
if((ch == blank) || (ch == comma) || (ch == dsign)) goto next_digit;
if(ch == minus) {
memcpy(&strout[(lw+1)-1], "minus ", 6);
lw = lw + 6;
goto next_digit;
}
if((n == 4) || (n == 8) || (n == 12)) tens = 1;
/* SPECIAL STUFF WHEN WE HIT THE DECIMAL POINT. */
if(ch == dot) {
tens = 1;
if(lw == 0) {
memcpy(&strout[(lw+1)-1], "zero ", 5);
lw = lw + 5;
}
memcpy(&strout[(lw+1)-1], "dollars and ", 12);
lw = lw + 12;
if(tmoney[(n+1)-1] == '0') {
if(tmoney[(n+2)-1] == '0') {
memcpy(&strout[(lw+1)-1], "zero ", 5);
lw = lw + 5;
n = n + 2;
}
}
goto next_digit;
}
/* CONVERT A CHARACTER INTO AN OFFSET. */
intch = ch - 48;
if(tens) {
if(intch <= 1) {
offset = 0;
if(intch == 1) offset = 10;
n = n + 1;
ch = tmoney[(n)-1];
intch = ch - 48 + offset;
}
else {
l = lenstr(tenvals[(intch+1) - 1], 10);
if(l > 0) {
memcpy(&strout[(lw+1)-1], tenvals[(intch+1)-1], l+1);
lw = lw + l + 1;
}
tens = 0;
goto next_digit;
}
}
l = lenstr(numbers[(intch+1)-1], 10);
if(l > 0) {
memcpy(&strout[(lw+1)-1], numbers[(intch+1)-1], l+1);
lw = lw + l + 1;
}
tens = 0;
if(((n == 3) || (n == 7) || (n == 11)) && (intch != 0)) {
memcpy(&strout[(lw+1)-1], "hundred ", 8);
lw = lw + 8;
}
if(n == 5) {
memcpy(&strout[(lw+1)-1], "million ", 8);
lw = lw + 8;
}
if(n == 9) {
memcpy(&strout[(lw+1)-1], "thousand ", 9);
lw = lw + 9;
}
goto next_digit;
cleanup:
memcpy(&strout[(lw+1)-1], "cents", 5);
lw = lw + 5;
/* Add the null terminator */
strout[(lw+1)-1] = '\0';
/* ALL DONE. */
return;
}
/**** End of DWRD function ****/
/**** Start of LENSTR function ****/
int lenstr(char *str, int count)
{
int i;
i = count - 1;
while (i >= 0) {
if (str[i] != ' ') break;
i--;
}
return (i+1);
}
/**** End of LENSTR function ****/
Making and Setting DLL
You can use a DLL (Dynamic Link Library) which you make for use in R:BASE. DLLs which you make can be used column and variable objects in Forms, Reports and Labels.
If you make a DLL, you must follow some rules of making DLLs.
Rules of making DLLs
Value of DLL's version
•int WINAPI RbDllVersion(void);
•You must specify to return 100.
DLL name which is displayed in the Combo Box
•const char* WINAPI RbDllSpec(void);
•You designate the DLL function's name which is displayed in the Combo Box.
DLL's ID
•int WINAPI RbDllId(void);
•It is the identity number of the DLL. You designate to return a number form 2 to 127.
The function called by Form when drawing field
•int WINAPI RbDllDraw(const char*, const HDC, long, long, long, long)
•Return value : 0 success / Not 0 fails
•Argument : const char* Data strings
•const HDC Device Context handle
•long Left upper corner X position of object
•long Left upper corner Y position of object
•long Right lower corner X position of object
•long Right lower corner Y position of object
The function called by Report or Label when drawing field
•int WINAPI RbDllDrawP(const char*, const HDC, long, long, long, long)
•Return value : 0 success / Not 0 fails
•Argument : const char* Data strings
•const HDC Device Context handle
•long Left upper corner X position of object
•long Left upper corner Y position of object
•long Right lower corner X position of object
•long Right lower corner Y position of object