Focal Point Banner


As of December 1, 2020, Focal Point is retired and repurposed as a reference repository. We value the wealth of knowledge that's been shared here over the years. You'll continue to have access to this treasure trove of knowledge, for search purposes only.

Join the TIBCO Community
TIBCO Community is a collaborative space for users to share knowledge and support one another in making the best use of TIBCO products and services. There are several TIBCO WebFOCUS resources in the community.

  • From the Home page, select Predict: WebFOCUS to view articles, questions, and trending articles.
  • Select Products from the top navigation bar, scroll, and then select the TIBCO WebFOCUS product page to view product overview, articles, and discussions.
  • Request access to the private WebFOCUS User Group (login required) to network with fellow members.

Former myibi community members should have received an email on 8/3/22 to activate their user accounts to join the community. Check your Spam folder for the email. Please get in touch with us at community@tibco.com for further assistance. Reference the community FAQ to learn more about the community.


Focal Point    Focal Point Forums  Hop To Forum Categories  WebFOCUS/FOCUS Forum on Focal Point     Custom user functions and type AnV

Read-Only Read-Only Topic
Go
Search
Notify
Tools
Custom user functions and type AnV
 Login/Join
 
Virtuoso
posted
I just wrote a custom user function in C that has one input parameter of type char* and another of type double* for the length. That function works fine as long as my alphanumeric inputs are of type An.

However, as soon as I input something that's actually AnV, the function crashes, even after I disable the entire function body.

Is it possible to write custom user functions (in C) that can handle AnV? If so, what's the trick? Does anyone have an example? The documentation on CUF's is rather... sparse.

P.S. I realise asking a question like this on the last working day before my X-mas holidays isn't ideal.

In advance, happy holidays everyone!


WebFOCUS 8.1.03, Windows 7-64/2008-64, IBM DB2/400, Oracle 11g & RDB, MS SQL-Server 2005, SAP, PostgreSQL 11, Output: HTML, PDF, Excel 2010
: Member of User Group Benelux :
 
Posts: 1669 | Location: Enschede, Netherlands | Registered: August 12, 2010Report This Post
Master
posted Hide Post
I don't have any experience with custom user functions in WebFOCUS, but I have decades of experience with the C programming language. Could you post your C function? I would like to "C" it (Boo, hiss).

Seriously, C strings are terminated with a zero byte. I would like to see your code so I can understand how you are receiving parameters and how you are trying to process them.


App Studio
WebFOCUS 8.1.05M
Windows, All Outputs
 
Posts: 594 | Location: Michigan | Registered: September 04, 2015Report This Post
Virtuoso
posted Hide Post
Sure, C strings are nul-terminated. FOCUS strings are not however, and that's what you get passed into your C function. The only way around that I could see was to also pass in input and output lengths, so that you know when to stop reading the FOCUS string. That is, if you can trust those lengths...

The problem can be reproduced with a rather minimal function:
void code128(double *inlen, char *incode, double* outlen, char *code128)
{
}


Where all parameters supposedly are values pre-allocated by WF. I know it's odd to use pointers for the lengths, but that's how WF user functions are specified apparently. See: http://infocenter.informationb...ource%2Ftopic236.htm

I know the above reproduces the problem, because I #if 0'd the entire function body at some point to see where the root of the problem was and that's where.


WebFOCUS 8.1.03, Windows 7-64/2008-64, IBM DB2/400, Oracle 11g & RDB, MS SQL-Server 2005, SAP, PostgreSQL 11, Output: HTML, PDF, Excel 2010
: Member of User Group Benelux :
 
Posts: 1669 | Location: Enschede, Netherlands | Registered: August 12, 2010Report This Post
Master
posted Hide Post
Well, that sucks.

So it looks like you need to convert your "AnV" string to a large "An" fixed-length one. Hopefully one large enough to always swallow up your variable-length string. But before you do that, you would need to append a special character -- like the pipe "|" char -- to your "AnV" to signal the end of the string.

In your C routine, you could then count characters in the "An" string until you find the pipe. Then use the C library's "malloc" function to create a buffer the size of your string (plus one for the null terminator byte). Use "memset" to initialize the buffer to all zeroes, then use "memcpy" to copy the characters over to that buffer. At that point your buffer should be able to be manipulated as a string using the C library's string functions.

A simpler alternative would be to replace the pipe character in the original "An" string with a zero, but that might cause a memory access violation.


App Studio
WebFOCUS 8.1.05M
Windows, All Outputs
 
Posts: 594 | Location: Michigan | Registered: September 04, 2015Report This Post
Gold member
posted Hide Post
Wep,

If your focus request has anv fields, they are passed to the user function as a character
string preceded by a two byte short length. Your C function, for instance, could look like:

int myfunc(char *instr, char *outstr)
{
short inlen; 
char localstr[257] ;

inlen = *(short*)instr ; 
inlen = (inlen>256) ? 256: inlen ;  /* max len here is 256 */
memcpy(localstr,instr+2,inlen) ;    /* copy input to local string max 256 chars */
*(localstr+inlen) = 0 ;                    /* null terminate local str */
printf("inlen is %d for string %s\n",inlen,localstr) ; 
return(0);
}


Try this and see what you get (there may be typos in the code). Smiler

This message has been edited. Last edited by: Edward Wolfgram,


IBI Development
 
Posts: 61 | Registered: November 15, 2005Report This Post
Master
posted Hide Post
Holy sparse documentation, Batman! Never came across that tidbit of information about the two byte short length.


App Studio
WebFOCUS 8.1.05M
Windows, All Outputs
 
Posts: 594 | Location: Michigan | Registered: September 04, 2015Report This Post
Virtuoso
posted Hide Post
That looks promising Edward.

An initial question: I see that you limit inlen to 256. Since the length is specified in 2 bytes, wouldn't it make sense to allow for a localstr of length 65537 instead of 257? (I use malloc/free, so the extra overhead doesn't really bother me)

For further understanding: Do you (or anyone else) happen to know how we can determine whether the input string is of type An or of type AnV?

Or should we create separate functions for An and AnV, like IBI already does in some cases? That would certainly be the cleaner implementation, as the input string length is superfluous in those cases anyway, but... Since we also have an output string parameter, we would require 4 different function implementations to catch all the different cases (An/An, AnV/An, An/AnV and AnV/AnV) - I'd much rather stick to one.


WebFOCUS 8.1.03, Windows 7-64/2008-64, IBM DB2/400, Oracle 11g & RDB, MS SQL-Server 2005, SAP, PostgreSQL 11, Output: HTML, PDF, Excel 2010
: Member of User Group Benelux :
 
Posts: 1669 | Location: Enschede, Netherlands | Registered: August 12, 2010Report This Post
Gold member
posted Hide Post
Hi Wep,

We currently don't expose the way this can be done for non-RSTAT functions (RSTAT is an IBI interface into a modeling language). I would suggest that if you will be reading anv fields, that your subroutine always uses anv fields, so you would just convert your input fixed char fields to temp anv fields (via define or compute) before calling your subroutine. You can also just put in a varchar flag as a parm to tell your subroutine if the char field is anv or not.

mychar(*inchar, *inflag, .... )

In my example, I just arbitrarily used 256 bytes as the limit. anv fields can go up to 32K in size.


IBI Development
 
Posts: 61 | Registered: November 15, 2005Report This Post
Virtuoso
posted Hide Post
Right, so one implementation for An/An and one for AnV/AnV - no mixing of types. Pretty much how you do it at IBI (SUBSTR and SUBSTV for example).

Now I just need to figure out what happened to my minimal example. That clearly should not crash - perhaps the crash occurs because the function doesn't modify the output string (such as nul-terminating it)? Time to get to work...


WebFOCUS 8.1.03, Windows 7-64/2008-64, IBM DB2/400, Oracle 11g & RDB, MS SQL-Server 2005, SAP, PostgreSQL 11, Output: HTML, PDF, Excel 2010
: Member of User Group Benelux :
 
Posts: 1669 | Location: Enschede, Netherlands | Registered: August 12, 2010Report This Post
Gold member
posted Hide Post
Wep,

Not exactly. What I am saying is that you can have just one version of your subroutine, and all character input parms are anv, and not fixed char. So, if you want to call your subroutine with a fixed char input, you would do something like this:

  
DEFINE FILE CAR 
TEMPA/A16V = CAR; 
MYOUT/A16V = MYFUNC(TEMPA,MYOUT); 
END 
 

This message has been edited. Last edited by: Edward Wolfgram,


IBI Development
 
Posts: 61 | Registered: November 15, 2005Report This Post
Virtuoso
posted Hide Post
That is another option indeed. Depends on whether I can get the AnV variant working. Currently I'm inclined to create both variants.


WebFOCUS 8.1.03, Windows 7-64/2008-64, IBM DB2/400, Oracle 11g & RDB, MS SQL-Server 2005, SAP, PostgreSQL 11, Output: HTML, PDF, Excel 2010
: Member of User Group Benelux :
 
Posts: 1669 | Location: Enschede, Netherlands | Registered: August 12, 2010Report This Post
  Powered by Social Strata  

Read-Only Read-Only Topic

Focal Point    Focal Point Forums  Hop To Forum Categories  WebFOCUS/FOCUS Forum on Focal Point     Custom user functions and type AnV

Copyright © 1996-2020 Information Builders