6 Coding for Portability

This chapter contains the following topics:

6.1 Portability Concepts

Portability is the ability to run a program on more than one system platform without modifying it. JD Edwards EnterpriseOne is a portable environment. This chapter presents considerations and guidelines for porting objects between systems.

Standards that affect the development of relational database systems are determined by:

  • ANSI (American National Standards Institute) standard

  • X/OPEN (European body) standard

  • ISO SQL standard

Ideally, industry standards enable users to work identically with different relational database systems. Each major vendor supports industry standards but also offers extensions to enhance the functionality of the SQL language. In addition, vendors constantly release upgrades and new versions of their products.

These extensions and upgrades affect portability. Due to the effect of software development on the industry, applications need a standard interface to databases-an interface that will not be affected by differences among database vendors. When vendors provide a new release, the effect on existing applications needs to be minimal. To solve portability issues, many organizations have moved to standard database interfaces, called open database connectivity (ODBC).

6.2 Portability Guidelines

Refer to these guidelines to develop business functions that comply with portability standards:

  • Business functions must be ANSI-compatible for portability.

    Since different computer platforms might present limitations, exceptions to this rule do exist. However, do not use a non-ANSI exception without approval from the Business Function Standards Committee.

  • Do not create a program that depends on data alignment, because each system aligns data differently by allocating bytes or words.

    For example: for a one-character field that is one byte. Some systems allocate only one byte for that field, while other systems allocate the entire word for the field.

  • Keep in mind that vendor libraries and function calls are system-dependent and exclusive to that vendor.

    This means that if the program is compiled using a different compiler, that particular function will fail.

  • Use caution when using pointer arithmetic because it is system-dependent and is based on the data alignment.

  • Do not assume that all systems will initialize a variable the same way.

    Always explicitly initialize variables.

  • Use caution when using an offset to explicitly retrieve a value within the data structure.

    This guideline also relates to data alignment. Use offset to define cache index.

  • Always typecast if your parameter does not match the function parameter.

    Note:

    JCHAR szArray[13] is not the same as (JCHAR *) in the function declaration. Therefore, typecast of (JCHAR *) is required for szArray for that particular function.
  • Never typecast on the left-hand side of the assignment statement, as it can result in a loss of data.

    For example, in the statement (short)nValue = (long),lValue will lose the value of the long integer if it is too large to fit into a short integer data type.

  • Do not use C++ comments (C++ comments begin with two forward slashes).

6.3 Preventing Common Server Build Errors and Warnings

JD Edwards EnterpriseOne business functions must be ANSI-compatible for portability. Since different computer platforms and servers have their own limitations, our business functions must comply with all server standards. This topic presents guidelines for coding business functions that correctly build on different servers.

6.3.1 Comments within Comments

Never use comments that are included in other comments. Each "/*" should be followed by subsequent "*/". Refer to these examples.

6.3.1.1 Example: C Comments that Comply with the ANSI Standard

Use this C standard comment block:

/**********************************************************************
* Correct Method of C Comments             *
*********************************************************************/
/* SAR 1234567 Begin*/
/* Populate the lpDS->OrderedPlacedBy value from the userID only in
   the ADD mode */
   if ( lpDS->cHeaderActionCode == _J('1'))
   {
      if (IsStringBlank(lpDS->szOrderedPlacedBy))
     .{
         jdeStrcpy((JCHAR *)(lpDS->szOrderedPlacedBy),
                   (const JCHAR *)(lpDS->szUserID));
      }/* End of defaulting in the user id into Order placed by
           if the later was left blank */ 
   }/* SAR 1234567 End */ 

6.3.1.2 Example: C Comments that Comply with the ANSI Standard

Use this C standard comment block:

/**********************************************************************
* Correct Method of C Comments             *
*********************************************************************/
/* SAR 1234567 Begin*/
/* Populate the lpDS->OrderedPlacedBy value from the userID only in
   the ADD mode */
   if ( lpDS->cHeaderActionCode == _J('1'))
   {
      if (IsStringBlank(lpDS->szOrderedPlacedBy))
     .{
         jdeStrcpy((JCHAR *)(lpDS->szOrderedPlacedBy),
                   (const JCHAR *)(lpDS->szUserID));
      }/* End of defaulting in the user id into Order placed by
           if the later was left blank */ 
   }/* SAR 1234567 End */ 

6.3.1.3 Example: Comments within Comments Cause Problems on Different Servers

This example shows that comments within comments can cause problem on different servers:

/**********************************************************************
 C Comments within Comments Causing Server Build Errors and Warnings 
 *********************************************************************/
/* SAR 1234567 Begin
/* Populate the lpDS->OrderedPlacedBy value from the userID only in
   the ADD mode */
*/
   if ( lpDS->cHeaderActionCode == _J('1'))
   {
      if (IsStringBlank(lpDS->szOrderedPlacedBy))
      {
         jdeStrcpy((JCHAR *)(lpDS->szOrderedPlacedBy),
                   (const JCHAR *)(lpDS->szUserID));
      }/* End of defaulting in the user id into the Order placed by
       /* if the later was left blank */
   }/* SAR 1234567 End */

6.3.2 New Line Character at the End of a Business Function

Some servers need a new line character at the end of the source and header file in order to build correctly. It is a best practice to ensure that a new line character is added at the end of each business function. Press the Enter key at the end of the code to add a new line character.

6.3.3 Use of Null Character

Be careful when using NULL character '\0'. This character starts with a back slash. Using '/0' is an error that is not reported by the compiler.

6.3.3.1 Example: Use of NULL Character

This example shows an incorrect and a correct use of the NULL character:

/*************Initialize Data Structures***************************/
/*Error Code*/
/* '/0' is used assuming it to be a NULL character*/
/* memset((void *)(&dsVerifyActivityRulesStatusCodeParms),
          (int)('/0'), sizeof(DSD4000260A));*/


/*Correct Use of NULL Character*/
memset((void *)(&dsVerifyActivityRulesStatusCodeParms),
       (int)('\0'), sizeof(DSD4000260A));

6.3.4 Lowercase Letters in Include Statements

When an external business function or table is included in the header file, use lowercase letters in the include statement. Uppercase letters cause build errors.

6.3.4.1 Example: Use of Lowercase Letters in Include Statements

This example shows the incorrect and correct use of lowercase letters in the include statement:

/**********************************************************************
* External Business Function Header Inclusions
********************************************************************/
/*Incorrect method of including external business function header*/
/*Include Statement Causing Build Warnings on Various Servers*/
   #include <B0000130.h>
/*Correct method of including external business function header*/
   #include <b0000130.h>

6.3.5 Initialized Variables that are Not Referenced

Each variable that is declared and initialized under the Variables Declaration section in the business function must be used in the program. For example: if the variable idReturnValue is initialized, then it must be used somewhere in the program.