Returning char* from external routine

Post questions here relative to DataStage Enterprise/PX Edition for such areas as Parallel job design, Parallel datasets, BuildOps, Wrappers, etc.

Moderators: chulett, rschirm, roy

timsmith_s
Participant
Posts: 54
Joined: Sun Nov 13, 2005 9:25 pm

Post by timsmith_s »

Its based on the assumption that DSEE will cleanup the memory that you alloc-ed. I am not saying that you are wrong. What I am saying is that its a big deal to just allocate something and pass it over the fence. I would have expected very clearly written documentation to explain this behavior. I have opened a ticket with IBM to hear their side of the story too. I will post my results from your suggest and IBM's feedback in the coming days - again, thank you.
Yuan_Edward
Participant
Posts: 73
Joined: Tue May 10, 2005 6:21 pm
Location: Sydney

Post by Yuan_Edward »

Just for your information only.

I tried to create my own trim function using C to remove the leading and/or trainling spaces/tabs and it worked.

I changed the contents of the input string and then the address of the input string was returned as the result. The string returned from Trim2 was correct (both leading and trailing spaces and tabs are trimmed) but I was surprised the contents of the input column DSLink2.nmi were not changed in DataStage!!!

Code: Select all

#include <stdio.h>
#include <string.h>
#include <ctype.h>

//To remove leading and/or trailing spaces and tabs
//Possible options are:
//    L: remove leading spaces and tabs
//    T: remove trailing spaces and tabs
//    B: remove leading and trailing spaces and tabs
char *Trim2(char *input, char *option)
{
    char option_std = toupper(option[0]);
    int len = strlen(input);
    int start_pos = 0, end_pos = len-1;

    //If input is null or the option is invalid, the input will be returned without any changes
    if(len <= 0 || (option_std != 'L' && option_std != 'T' && option_std != 'B'))
    {
        return input;
    }

    //look for the last leading space/tab
    if(option_std == 'L' || option_std == 'B')
    for(;start_pos<=len-1;start_pos++)
    {
        if(input[start_pos] != ' ' && input[start_pos] != '\t') break;
    }

    //look for the first trailing space/tab
    if(option_std == 'T' || option_std == 'B')
    for(;end_pos>=0;end_pos--)
    {
        if(input[end_pos] != ' ' && input[end_pos] != '\t') break;
    }

   input[end_pos+1] = '\0';

   return input+start_pos;
}

Code: Select all

*** Internal Generated Transformer Code follows:
0001: //
0002: // Generated file to implement the V0S1_repos_Transformer_1 transform operator.
0003: //
0004: 
0005: // define external functions used
0006: extern string Trim2(string string,string option);
0007: 
0008: // define our input/output link names
0009: inputname 0 DSLink2;
0010: outputname 0 DSLink4;
0011: 
0012: initialize {
0013: 	// define our row rejected variable
0014: 	int8 RowRejected0;
0015: 
0016: 	// define our null set variable
0017: 	int8 NullSetVar0;
0018: 
0019: 	// declare our intermediate variables for this section
0020: 	string InterVar0_0;
0021: 	string InterVar0_1;
0022: 	string InterVar0_2;
0023: 
0024: 	// initialise constant values which require conversion
0025: 	InterVar0_0 = " ";
0026: 	InterVar0_1 = "B";
0027: 	InterVar0_2 = "B";
0028: 	// Stage variable declaration and initialisation
0029: 	string StageVar0_StageVar;
0030: 	StageVar0_StageVar = "";
0031: }
0032: 
0033: mainloop {
0034: 	// initialise our row rejected variable
0035: 	RowRejected0 = 1;
0036: 
0037: 	// declare our intermediate variables for this section
0038: 	string InterVar0_3;
0039: 
0040: 	// evaluate the stage variables first
0041: 	StageVar0_StageVar = DSLink2.nmi;
0042: 
0043: 	// evaluate columns (no constraints) for link: DSLink4
0044: 	DSLink4.nmi_trimspace = trimc_string(DSLink2.nmi , InterVar0_0 , InterVar0_1);
0045: 	DSLink4.nmi_trimtab = trimc_string(DSLink2.nmi , char_from_num(9) , InterVar0_1);
0046: 	DSLink4.nmi_trim = trimc_string(DSLink2.nmi);
0047: 	InterVar0_3 = Trim2(StageVar0_StageVar , InterVar0_2);
0048: 	DSLink4.nmi_trim2 = InterVar0_3;
0049: 	DSLink4.nmi_original = DSLink2.nmi;
0050: 	DSLink4.stagevar_original = StageVar0_StageVar;
0051: 	writerecord 0;
0052: 	RowRejected0 = 0;
0053: }
0054: 
0055: finish {
0056: }
0057: 
*** End of Internal Generated Transformer Code
timsmith_s wrote:Its based on the assumption that DSEE will cleanup the memory that you alloc-ed. I am not saying that you are wrong. What I am saying is that its a big deal to just allocate something and pass it over the fence. I would have expected very clearly written documentation to explain this behavior. I have opened a ticket with IBM to hear their side of the story too. I will post my results from your suggest and IBM's feedback in the coming days - again, thank you.
Edward Yuan
timsmith_s
Participant
Posts: 54
Joined: Sun Nov 13, 2005 9:25 pm

Post by timsmith_s »

Very true. Maybe the Trim() was a bad choice on my part. your example is in the clear because it uses less than the max inbound buffer length. I should have suggested StringCat or the like to illustrate my point. Nevertheless, thank you for the background.
Post Reply