The following sample program is intended to show how the binder C/C++ programming interface could be used by an application written in C language.
#pragma nomargins nosequence
/**********************************************************************/
/* */
/* LICENSED MATERIALS - PROPERTY OF IBM */
/* */
/* 5650-ZOS */
/* */
/* COPYRIGHT IBM CORP. 1977, 2013 */
/* */
/* STATUS = HPM7770 */
/* */
/* FUNCTION: Example program which uses the Binders C/C++ programming */
/* interface. Here we call both the Binder API and */
/* fast data access with the C/C++ API. */
/* */
/* PROCESSING: */
/* A. Main program - main() */
/* 1) Set up CU_TYPE array */
/* 2) Calls test_binder_api() */
/* 3) Calls test_fdata_api() */
/* */
/* B. Sample Binder API program - test_binder_api() */
/* 1) Includes a module */
/* 2) Prints classes: calls print_classes() */
/* 3) Prints sections with CU numbers & compile units: */
/* calls print_compile_units() */
/* */
/* C. Sample fast data access program - test_fdata_api() */
/* 1) Includes a module */
/* 2) Prints classes: calls fd_print_classes() */
/* 3) Prints sections with CU numbers & compile units: */
/* calls fd_print_compile_units() */
/* */
/* */
/* HELPER FUNCTIONS: */
/* A. Print classes - print_classes() & fd_print_classes() */
/* 1) Loop on getN output to get all classes */
/* 2) Process all the sections retrieved: */
/* calls print_name_entry() */
/* */
/* B. Print sections with CU numbers and compile units - */
/* print_compile_units() & fd_print_compile_units() */
/* 1) Loop on getN output to get all sections */
/* 2) Process all the sections retrieved */
/* calls print_cu_name_entry() */
/* 3) Loop on getC output to get all the compile units */
/* 4) Process all the CUs retrieved */
/* calls print_cu_entry() */
/**********************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
/********************************/
/* Binder's C/C++ Include Files */
/********************************/
#define _IEW_TARGET_RELEASE _IEW_CURRENT_
#include <__iew_api.h>
/********************************/
/* Prototypes */
/********************************/
void test_binder_api(const char *);
void print_classes(_IEWAPIContext* _context);
void print_compile_units(_IEWAPIContext* _context);
void test_fdata_api(const char *);
void fd_print_classes(_IEWFDContext* _context);
void fd_print_compile_units(_IEWFDContext* _context);
void print_cu_entry(FILE* _file, _IEWCUIEntry* _buf, int print_cuinfo);
void print_cu_name_entry(FILE* _file, _IEWNameListEntry* _buf);
void print_name_entry(FILE* _file, _IEWNameListEntry* _buf);
char * CU_TYPE[0xFF];
/************************************************************/
/* Name: main() */
/* Input: */
/* returns: */
/* Description: Sample Binder C/C++ API program */
/* 1. Use Binder APIs which include a module and print */
/* classes, sections with CU numbers, and compile */
/* units. */
/* 2. Use Fastdata APIs which include a module and print */
/* classes, sections with CU numbers, and compile */
/* units. */
/************************************************************/
int main(const int argc, const char **argv)
{
int i;
for (i=0; i<=0xff; i++) {
CU_TYPE[i] = "--invalid--";
}
CU_TYPE[0X00]="LM";
CU_TYPE[0X01]="Gen'd by PUTD API V1";
CU_TYPE[0X02]="Gen'd by PUTD API V2+";
CU_TYPE[0X10]="PO1";
CU_TYPE[0X11]="OBJ";
CU_TYPE[0X12]="XOBJ";
CU_TYPE[0X13]="GOFF";
CU_TYPE[0X14]="Unknown";
CU_TYPE[0X15]="Workmod";
CU_TYPE[0X16]="Gen'd by binder";
CU_TYPE[0X20]="PO2";
CU_TYPE[0X30]="PO3";
CU_TYPE[0X41]="PO4, z/OS 1.3 compat";
CU_TYPE[0X42]="z/OS 1.5 compat";
CU_TYPE[0X43]="z/OS 1.7 compat";
CU_TYPE[0X51]="PO5, z/OS 1.8 compat";
/* test binder api */
test_binder_api(argv[1]);
/* test fdata api */
test_fdata_api(argv[1]);
return 0;
}
/************************************************************/
/* Name: test_binder_api() */
/* Input: None */
/* returns: None */
/* Description: */
/* Example application which includes a module and */
/* prints classes, sections with CU numbers, and */
/* compile units. */
/************************************************************/
void test_binder_api(const char *path_name) {
_IEWAPIContext *apiCnxt, *retCnxt; /* APIContext */
_IEWList* files_list;
_IEWList* exits_list;
unsigned int rc, reason;
/* initialize api flags */
_IEWAPIFlags apiflags= {0,0,0,0,0,0,0,0,0};
/* files list variables */
char* files[] = { "PRINT " };
char* files_val[] = { "./temp" };
/* exits list variables */
struct _exit_address {
void *entry_point;
void *user_data;
void *severity_level;
} exits_address;
struct _exit_address exitsA;
struct _exit_address *exitsPtr;
char* exits[] = { "SAVE" };
void* exits_val[1];
/* parms for __iew_openW() */
char *parms="MAP=Y,XREF=Y,CASE=MIXED,TERM=Y,LIST=ALL";
if (!__isPosixOn())
files_val[0] = "SYSPRINT";
exitsA.entry_point = NULL;
exitsA.user_data = NULL;
exitsA.severity_level = 0;
exitsPtr = &exitsA;
exits_val[0] = exitsPtr;
/* create file list for __iew_openW() */
files_list = __iew_create_list(1,files,(void **)files_val);
if (files_list == NULL)
{
fprintf(stderr, " create_list error: files list is null.\n");
return;
}
/* create exits list for __iew_openW() */
exits_list = __iew_create_list(1,exits,exits_val);
if (exits_list == NULL)
{
fprintf(stderr," create_list error: exits_val %x.\n", exits_val[0]);
fprintf(stderr," create_list error: *exits_val %x.\n", *exits_val);
fprintf(stderr," create_list error: exits list is null.\n");
return;
}
/* open workmod session, load BINDER, create api context with */
/* target release = <see above: #define _IEW_TARGET_RELEASE>, intent = access
*/
apiCnxt = __iew_openW(_IEW_TARGET_RELEASE, _IEW_ACCESS,
files_list, exits_list,
parms,
&rc,&reason);
if (apiCnxt == NULL)
{
fprintf(stderr," openW error: apiCnxt is null.\n");
fprintf(stderr," openW error: rc=%u, rs=<0X%.8X>.\n",rc,reason);
return;
}
else
{
fprintf(stderr," openW: rc=%u, rs=<0X%.8X>.\n",rc,reason);
}
/* set api flags for __iew_includeName() */
apiflags.__imports = 1;
apiflags.__aliases = 1;
apiflags.__attrib = 1;
/* read in program object via __iew_includeName() */
rc = __iew_includeName(apiCnxt,path_name,"",apiflags);
if (rc)
{
fprintf(stderr," includeName error: apiCnxt is null.\n");
fprintf(stderr," includeName error: rc=%u, rs=<0X%.8X>.\n",
rc,__iew_get_reason_code(apiCnxt));
}
else
{
fprintf(stderr," includeName: rc=%u, rs=<0X%.8X>.\n",
rc,__iew_get_reason_code(apiCnxt));
/* print all class names from workmod */
print_classes(apiCnxt);
/* print all compile units from workmod */
print_compile_units(apiCnxt);
}
/* set api flags for __iew_closeW() */
apiflags.__protect = 1;
/* close workmod session, delete api context */
retCnxt = __iew_closeW(apiCnxt, apiflags, &rc, &reason);
if (retCnxt)
{
fprintf(stderr," closeW: ERROR, context is not NULL. \n");
}
fprintf(stderr," closeW: return code = %X, rs =<0X%.8X> \n",
rc, reason);
return;
}
/************************************************************/
/* Name: print_classes() */
/* Input: None */
/* returns: None */
/* Description: */
/* Print classes */
/************************************************************/
void print_classes(_IEWAPIContext* _context) {
_IEWNameListEntry *class_name;
unsigned int num_of_classes = 0; /* number of classes */
int i,count;
/* loop on __iew_getN() api to get all classes */
while ((count = __iew_getN(_context,_IEW_CLASS, &num_of_classes,
&class_name)) > 0)
{
fprintf(stderr,"print_classes: name count = %d\n",count);
if(class_name)
{
/* process all CSECTs retrieved */
for (i=0; i < count; i++)
{
print_name_entry(stderr,&class_name[i]);
}
}
else
fprintf(stderr,"print_classes: name buffer is NULL! \n");
}
if (__iew_eod(_context, (void **) &class_name, "B_BNL") != 0)
{
fprintf(stderr," getN: ERROR, not end of data \n");
fprintf(stderr," getN: rc=%u, rs=<0X%.8X>.\n",
__iew_get_return_code(_context),__iew_get_reason_code(_context));
}
}
/************************************************************/
/* Name: print_compile_units() */
/* Input: None */
/* returns: None */
/* Description: */
/* Print sections with CU numbers, and compile units. */
/************************************************************/
void print_compile_units(_IEWAPIContext* _context) {
unsigned int num_of_classes = 0; /* number of classes */
int i,count,loopctr,print_cuinfo=0;
/* set the first CU entry to zero, so one record of all */
/* compile units are returned */
int cu_val[]= {0};
/* void *name_entry, *cu_entry; */
_IEWNameListEntry *sect_name;
_IEWCUIEntry *cui_entry;
/* loop on getN() api to get all sections */
while ((count = __iew_getN(_context,_IEW_SECTION, &num_of_classes,
§_name)) > 0)
{
fprintf(stderr,"print sections with CU numbers: name count = %d\n",
count);
if(sect_name)
{
/* process all CSECTs retrieved */
for (i=0; i < count; i++)
{
print_cu_name_entry(stderr,§_name[i]);
}
}
else
fprintf(stderr,"print_compile_units: name entry is NULL! \n");
}
if (__iew_eod(_context, (void **) §_name, "B_BNL") != 0)
{
fprintf(stderr," getN: ERROR, not end of data \n");
fprintf(stderr," getN: rc=%u, rs=<0X%.8X>.\n",
__iew_get_return_code(_context),__iew_get_reason_code(_context));
return;
}
/* loop on get_C() api to get all compile units */
loopctr = 0;
while ((count = __iew_getC(_context,cu_val,
&cui_entry)) > 0)
{
loopctr++;
if (loopctr==1 &&
cui_entry[0].__cui_cu==0 &&
cui_entry[0].__cui_source_cu==0 &&
cui_entry[0].__cui_concat==0 &&
cui_entry[0].__cui_type>=0x42)
print_cuinfo = 1;
fprintf(stderr,"print_compile_units: cu count = %d\n",count);
if(cui_entry)
{
/* process all CUs retrieved */
for (i=0; i < count; i++)
{
print_cu_entry(stderr,&cui_entry[i],print_cuinfo);
}
}
else
fprintf(stderr,"print_compile_units: CU entry is NULL! \n");
}
if (__iew_eod(_context, (void **) &cui_entry, "B_CUI") != 0)
{
fprintf(stderr," getC: ERROR, not end of data \n");
fprintf(stderr," getC: rc=%u, rs=<0X%.8X>.\n",
__iew_get_return_code(_context),__iew_get_reason_code(_context));
}
}
/************************************************************/
/* Name: test_fdata_api() */
/* Input: None */
/* returns: None */
/* Description: */
/* Example application which includes a module and */
/* prints classes, sections with CU numbers, and */
/* compile units. */
/************************************************************/
void test_fdata_api(const char *path_name) {
_IEWFDContext *fdCnxt, *fdRetCnxt; /* FDContext */
unsigned int rc, reason;
/* read in program object via __iew_fd_startName() */
/* open session, create fd context with */
/* target release = <see above: #define _IEW_TARGET_RELEASE> */
fdCnxt =__iew_fd_open(_IEW_TARGET_RELEASE,
&rc,&reason);
if (fdCnxt == NULL)
{
fprintf(stderr," fd_open error: fdCnxt is null.\n");
fprintf(stderr," fd_open error: rc=%u, rs=<0X%.8X>.\n",rc,reason);
return;
}
else
{
fprintf(stderr," fd_open rc=%u, rs=<0X%.8X>.\n",rc,reason);
}
/* starting a session with a path */
rc = __iew_fd_startName(fdCnxt,path_name,"");
fprintf(stderr, " fd_startName rc =%d \n", rc);
if (rc)
{
fprintf(stderr," fd_startName error: rc=%u, rs=<0X%.8X>.\n",
rc,__iew_fd_get_reason_code(fdCnxt));
}
else
{
fprintf(stderr," fd_startName: rc=%u, rs=<0X%.8X>.\n",
rc,__iew_fd_get_reason_code(fdCnxt));
/* print all class names */
fd_print_classes(fdCnxt);
/* print all compile units */
fd_print_compile_units(fdCnxt);
}
/* end a session */
fdRetCnxt = __iew_fd_end(fdCnxt,&rc,&reason);
if (fdRetCnxt)
{
fprintf(stderr," fd_end: ERROR, context is not NULL \n");
}
fprintf(stderr," fd_end: return code = %X, rs =<0X%.8X> \n",
rc,reason);
return;
}
/************************************************************/
/* Name: fd_print_classes() */
/* Input: None */
/* returns: None */
/* Description: */
/* Print classes */
/************************************************************/
void fd_print_classes(_IEWFDContext* _context) {
_IEWNameListEntry *class_name;
int i,count;
/* loop on __iew_fd_get_N() api to get all classes */
while ((count = __iew_fd_getN(_context,_IEW_CLASS,
&class_name)) > 0)
{
fprintf(stderr,"fd_print_classes: name count = %d\n",count);
if(class_name)
{
/* process all CSECTs retrieved */
for (i=0; i < count; i++)
{
print_name_entry(stderr,&class_name[i]);
}
}
else
fprintf(stderr,"fd_print_classes: name buffer is NULL! \n");
}
if (__iew_fd_eod(_context, (void **)&class_name, "B_BNL") != 0)
{
fprintf(stderr," fd_getN: ERROR, not end of data \n");
fprintf(stderr," fd_getN: rc=%u, rs=<0X%.8X>.\n",
__iew_fd_get_return_code(_context),
__iew_fd_get_reason_code(_context));
}
}
/************************************************************/
/* Name: fd_print_compile_units() */
/* Input: None */
/* returns: None */
/* Description: */
/* Print sections with CU numbers, and compile units. */
/************************************************************/
void fd_print_compile_units(_IEWFDContext* _context) {
int i,count,loopctr,print_cuinfo=0;
/* set the first CU entry to zero, so one record of all */
/* compile units are returned */
int cu_val[]= {0};
_IEWNameListEntry * sect_name;
_IEWCUIEntry * cui_entry;
/* loop on fd_get_N() api to get all sections */
while ((count = __iew_fd_getN(_context,_IEW_SECTION,
§_name)) > 0)
{
fprintf(stderr,"print sections with CU numbers: name count = %d\n",
count);
if(sect_name)
{
/* process all CSECTs retrieved */
for (i=0; i < count; i++)
{
print_cu_name_entry(stderr,§_name[i]);
}
}
else
fprintf(stderr,"fd_print_compile_units: name entry is NULL! \n");
}
if (__iew_fd_eod(_context, (void **)§_name, "B_BNL") != 0)
{
fprintf(stderr," fd_getN: ERROR, not end of data \n");
fprintf(stderr," fd_getN: rc=%u, rs=<0X%.8X>.\n",
__iew_fd_get_return_code(_context),
__iew_fd_get_reason_code(_context));
return;
}
/* loop on fd_get_C() api to get all compile units */
loopctr=0;
while ((count = __iew_fd_getC(_context,cu_val,
&cui_entry)) > 0)
{
loopctr++;
if (loopctr==1 &&
cui_entry[0].__cui_cu==0 &&
cui_entry[0].__cui_source_cu==0 &&
cui_entry[0].__cui_concat==0 &&
cui_entry[0].__cui_type>=0x42)
print_cuinfo = 1;
fprintf(stderr,"fd_print_compile_units: cu count = %d\n",count);
if(cui_entry)
{
/* process all CUs retrieved */
for (i=0; i < count; i++)
{
print_cu_entry(stderr,&cui_entry[i],print_cuinfo);
}
}
else
fprintf(stderr,"fd_print_compile_units: CU entry is NULL! \n");
}
if (__iew_fd_eod(_context, (void **)&cui_entry, "B_CUI") != 0)
{
fprintf(stderr," fd_getC: ERROR, not end of data \n");
fprintf(stderr," fd_getC: rc=%u, rs=<0X%.8X>.\n",
__iew_fd_get_return_code(_context),
__iew_fd_get_reason_code(_context));
}
}
/*************************************************************/
/* Name: print_cu_entry() */
/* Input: file, buf */
/* returns: */
/* Description: print out some CU entries */
/*************************************************************/
void print_cu_entry(FILE* _file, _IEWCUIEntry* _buf, int print_cuinfo) {
fprintf(_file,
"getC: cu=%5u, src cu=%5u, concat=%4x, seq=%3u, type(%4x)=%-25s,"
" src type(%4x)=%-25s\n",
_buf->__cui_cu,
_buf->__cui_source_cu,
_buf->__cui_concat,
_buf->__cui_c_seq,
_buf->__cui_type,
CU_TYPE[_buf->__cui_type],
_buf->__cui_c_type,
CU_TYPE[_buf->__cui_c_type]);
if (print_cuinfo) {
fprintf(_file,
" source info: ddname=%8s\n"
" current: dsn=%44.*s, member=%8.*s\n"
" path(%u)=%.*s\n"
" orig: dsn=%44.*s, member=%8.*s\n"
" path(%u)=%.*s\n",
_buf->__cui_ddname,
_buf->__cui_dsname_len, _buf->__cui_dsname_ptr,
_buf->__cui_member_len, _buf->__cui_member_ptr,
_buf->__cui_path_len,
_buf->__cui_path_len, _buf->__cui_path_ptr,
_buf->__cui_c_dsname_len, _buf->__cui_c_dsname_ptr,
_buf->__cui_c_member_len, _buf->__cui_c_member_ptr,
_buf->__cui_c_path_len,
_buf->__cui_c_path_len, _buf->__cui_c_path_ptr);
}
}
/*************************************************************/
/* Name: print_cu_name_entry() */
/* Input: file, name */
/* returns: */
/* Description: print out some NAME entries for CU */
/*************************************************************/
void print_cu_name_entry(FILE* _file,_IEWNameListEntry* _name) {
int i;
char temp_str[1025];
temp_str[0] = '\0';
if (((char*)_name->__bnl_name_ptr)[0] == 0) {
sprintf(temp_str,"PC%06X",*((int*)_name->__bnl_name_ptr));
}
else {
sprintf(temp_str,"%.*s",_name->__bnl_name_chars,
(char*)_name->__bnl_name_ptr);
}
fprintf(_file,
"%-16s : len - %3d, cu - %3u, count - %3d \n",
temp_str, _name->__bnl_name_chars,
_name->__bnl_u1.__bnl_sect_cu,_name->__bnl_elem_count);
}
/*************************************************************/
/* Name: print_name_entry() */
/* Input: file, buf */
/* returns: */
/* Description: print out some NAME entries */
/*************************************************************/
void print_name_entry(FILE* _file,_IEWNameListEntry* _name) {
int i;
char temp_str[1025];
temp_str[0] = '\0';
if (((char*)_name->__bnl_name_ptr)[0] == 0) {
sprintf(temp_str,"PC%06X",*((int*)_name->__bnl_name_ptr));
}
else {
sprintf(temp_str,"%.*s",_name->__bnl_name_chars,
(char*)_name->__bnl_name_ptr);
}
fprintf(_file,
"%-16s : len - %3d, count - %3d , attributes - 0x%02X\n",
temp_str, _name->__bnl_name_chars,
_name->__bnl_elem_count,_name->__bnl_bind_flags);
}