Older Keyword API

The Pre-IDL 5.5 Keyword API

Versions of IDL prior to IDL 5.5 used a different, but similar, keyword processing API to that found in the current versions. The remainder of this section provides information of interest to programmers maintaining older system routines that were written to that API.

Note: NV5 Geospatial Solutions recommends that all new code be written using the new keyword processing API. The older API continues to be supported for backwards compatibility, and there is no urgent reason to convert code that uses it. However, the effort of converting old code to the new API is minimal, and can be beneficial.

Background

If you have system routines that were written for use with versions of IDL older than IDL 5.5, your code uses an older keyword processing API, described in “Processing Keywords With IDL_KWGetParams()”, that including the following obsolete elements:

This old API served for many years, but it had some unfortunate features that made it hard to use correctly:

Advantages of the IDL 5.5 API

In contrast, keyword processing, in IDL 5.5 and later is built around the IDL_KWProcessByOffset() function, has the following advantages:

Differences And Similarities Between APIs

The current IDL keyword processing API was designed to minimize the changes necessary to convert existing older code. The differences and similarities between these APIs are summarized below:

Converting Existing Code To The New API

To convert code that uses the old API to the new version:

The Transitional API

We recommend that you convert your code to the reentrant keyword API based around the IDL_KWProcessByOffset() and IDL_KWFree() functions. This is almost always a straightforward operation, and the resulting code has all of the advantages discussed in “Advantages Of The IDL 5.5 API”. However, there is another alternative that may be useful is some situations. A third keyword API, built around the IDL_KWProcessByAddr() function exists that provides the benefits of eliminating the confusing IDL_KWCleanup() function, while not requiring the use of static non-reentrant separate variables to change.

The transitional API is a halfway measure designed to solve the worst problems of the old API while requiring the minimum amount of change to your code:

int IDL_KWProcessByAddr(int argc, IDL_VPTR *argv, char *argk,       

   IDL_KW_PAR *kw_list, IDL_VPTR *plain_args,

   int mask, int *free_required)

 

void IDL_KWFree(void)

where:

argc, argv, argk, plain_args, mask

These arguments are the same as those required by IDL_KWProcessByOffset().

kw_list

An array of IDL_KW_PAR structures, in the absolute address form required by the old IDL_KWGetParams() keyword API (the specified and value fields use address to static C variables).

free_required

The address of an integer to be filled in by IDL_KWProcessByAddr(). If set to TRUE, the caller must call IDL_KWFree() prior to exit from the routine.

Example: Converting From The Old Keyword API

To illustrate the use of the old keyword API, the transitional API, and the new reentrant API, this section provides an extremely simple example, written three times, once with each API.

Another useful comparison is to compare the example Keyword Examples on with its original version written with the old API which can be found in “Keyword Examples”.

Old API

IDL_VPTR IDL_someroutine(int argc, IDL_VPTR *argv, char *argk)

{

static IDL_VPTR count_var;

static IDL_LONG debug;

static IDL_STRING name;

static IDL_KW_PAR kw_pars[] = {

{ "COUNT", 0,1,IDL_KW_OUT|IDL_KW_ZERO,0,IDL_CHARA(count_var)},

{ "DEBUG", IDL_TYP_LONG, 1, IDL_KW_ZERO, 0,IDL_CHARA(debug) },

{ "NAME", IDL_TYP_STRING, 1, IDL_KW_ZERO, 0,IDL_CHARA(name) },

 

{ NULL }

};

 

IDL_VPTR result;

IDL_KWCleanup(IDL_KW_MARK);

argc = IDL_KWGetParams(argc,argv,argk,kw_pars,(IDL_VPTR *)0,1);

 

/* Your code goes here. Keyword values are available in the

* static variables.*/

 

/* Cleanup keywords before leaving */

IDL_KWCleanup(IDL_KW_CLEAN);

return(result);

}

Transitional API

The transitional API provides the benefits of simplified and straightforward cleanup, but does not require you to alter your IDL_KW_PAR array or gather the keyword variables into a common structure. The resulting code is very similar to the old API.

IDL_VPTR IDL_someroutine(int argc, IDL_VPTR *argv, char *argk)

{

static IDL_VPTR count_var;

static IDL_LONG debug;

static IDL_STRING name;

static IDL_KW_PAR kw_pars[] = {

{"COUNT", 0, 1, IDL_KW_OUT|IDL_KW_ZERO,

0,IDL_KW_ADDROF(count_var) },

{ "DEBUG", IDL_TYP_LONG,1,IDL_KW_ZERO,0,IDL_KW_ADDROF(debug)},

{ "NAME", IDL_TYP_STRING,1,IDL_KW_ZERO,0,IDL_KW_ADDROF(name)},

{ NULL }

};

 

int kw_free;

IDL_VPTR result;

 

argc = IDL_KWProcessByAddr(argc, argv, argk, kw_pars,

   (IDL_VPTR *) 0, 1, &kw_free);

 

/* Your code goes here. Keyword values are available in the

* static variables.*/

 

/* Cleanup keywords before leaving */

if (kw_free) IDL_KWFree();

 

return(result);

}

 

New Reentrant API

IDL_VPTR IDL_someroutine(int argc, IDL_VPTR *argv, char *argk)

{

typedef struct {

IDL_KW_RESULT_FIRST_FIELD; /* Must be first entry in struct */ IDL_VPTR count_var;

IDL_LONG debug;

IDL_STRING name;

} KW_RESULT;

static IDL_KW_PAR kw_pars[] = {

{ "COUNT", 0, 1, IDL_KW_OUT | IDL_KW_ZERO,

0, IDL_KW_OFFSETOF(count_var) },

{ "DEBUG", IDL_TYP_LONG, 1, IDL_KW_ZERO,

0, IDL_KW_OFFSETOF(debug) },

{ "NAME", IDL_TYP_STRING, 1, IDL_KW_ZERO,

0, IDL_KW_OFFSETOF(name) },

{ NULL }

};

 

KW_RESULT kw;

IDL_VPTR result;

 

argc = IDL_KWProcessByOffset(argc, argv, argk, kw_pars, (IDL_VPTR *) 0, 1, &kw);

 

/* Your code goes here. Keyword values are available in the

* kw struct.*/

 

/* Cleanup keywords before leaving if necessary */

IDL_KW_FREE;

 

return(result);

}