23
Mon, Dec
1 New Articles

Free-Format: Using C Functions in RPG IV

RPG
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Integrating C functions with normal RPG IV gives you the best of both worlds.

 

Editor's Note: This article is an excerpt from the MC Press book Functions in Free-Format RPG IV.

 

Most RPG programmers don't know the C programming language and avoid technical articles and discussions that have anything to do with it. In fact, I will go so far as to say that many RPG programmers get a little “testy” when someone says that C is better than RPG, since it is newer, uses functions, etc., etc., etc. I have to admit that I was not interested in the C language when it was first available. I was busy on a midrange IBM platform that didn’t even have a C compiler.

 

All that changed in 1993 when I took some graduate-level classes in computer science at a major university. I was faced with classes that used C exclusively for programming lab assignments. Oh, boy! I was cornered. I faced this new challenge and tore into it rigorously. C was different, for sure, but it didn’t take too long to appreciate a concept that is pervasive in this language but was conspicuously absent in RPG—user-written functions!

 

It took a few months for me to get used to this new style of coding. By the middle of the semester, I was pounding it out as well as those who knew C before coming to classes.

 

After the college classes, I went back into the world of RPG, with RPG IV making its appearance in late 1994. The new incarnation of RPG was easy to learn and in a few years became the standard on the AS/400, iSeries, or whatever the system name of the day was.

 

Sometime around V3R2/V3R7, IBM provided support for a new idea: subprocedures in RPG IV. These new subprocedures required the use of ILE, binding, and a non-default activation group. The concept didn’t exactly take the RPG programming world by storm. It has taken many years for us to adopt these cute little mini-programs that return a value. To tie my C experience into this discussion, the subprocedure facility was and is user-written functions—just like the ones in C.

 

So now, when we need a function of some kind, do we code a subprocedure? To answer my own question: maybe. I hedge because there are dozens of functions ready to go in a function “library” provided to us RPG programmers. I refer of course to the C language operations. But why? Isn’t RPG IV good enough?

 

It's true that RPG IV has a rich complement of opcodes and built-in functions, so why even consider accessing functions designated for the C language? The answer is that the C language provides some functions that we don’t have in RPG IV, as well as some functions that are simply more efficient than our native RPG operations. This leads us to believe that we need to drop the adversarial attitude we have acquired about the C language and see what it can do for us. With a little learning and practice, we can integrate some C functions into our everyday RPG IV code, giving us the best of both language worlds.

“Doing It” Details

To access a C function, you need to know the function’s interface, including the function name, number of parameters, parameter data types, and the return value.

 

To see how a C function might be useful to an RPG program, let’s look at a couple of examples. First, let’s look at a need for a random number. RPG IV does not have a random number function. To get a random number, we should look at the scheme used by the C language. There is an operation called rand that returns the next random number from a previous value. However, rand requires that you initialize the internal value that rand uses to generate the next random number. This initialization is called “seeding” the random number generator. This is done with the C operation called srand. So to get a random number, we must use both srand and rand. The output (return value) from rand is an unsigned integer whose value can be anywhere from 0 to 32767. If we want some other range, say 1 to 100, then we must do some range manipulation. Srand has no return value; it takes a parameter value and sets the internal random number initial value. There is something you need to know about this scheme. The parameter you send to srand needs to be random. Here’s why: rand produces output that is predictable in the sense that if you give it value x, it returns y. If, at some time later, you happen to give it the same value of x, it predictably returns y. To avoid any problems, don’t use a constant as the parameter to srand. My choice is to use the microseconds from the system clock from the %timestamp BIF (only milliseconds are available right now). This is pretty random by itself. Here’s the code that I would suggest:

 

H    Bnddir('QC2LE')

D Seed            S              5u 0 inz(0)

D Index           s              5u 0

//   Prototypes for C functions – and use of Extproc keyword

D Set_Random      pr                  Extproc('srand')

D  Seed                          5u 0 Value

D Get_Random      pr             5u 0 Extproc('rand')

/free

Dow Seed = 0;

Seed = %subdt(%timestamp():*MS)/1000; // Milliseconds from time

If Seed <> 0;

Set_Random(Seed);        // Set the seed

Endif;

Enddo;

// Obtain the random number,

// then scale it to be from 1 to 100

Index  = Get_Random();        // Index now 0 to 32767

Index  = %rem(index:100);     // Index now 0 to 99

Index += 1;                   // Index now 1 to 100

*Inlr = *On;

/end-free

 

At the end of the routine, the random number derived from the C function rand (Prototype Get_Random) is scaled using division by 100 and using the remainder (0 to 99), and then adding 1 to get a number from 1 to 100. If your needs include producing a list of random numbers with no duplicates, you will need to set up a loop after the “seed” section, storing the results of the random number computation (possibly in an array) and verify each time that you get a new number that it is not a duplicate. If it is a duplicate, throw it out and go through the loop again until you have your list, with no duplicates.

 

The little program above uses data type “u” for the seed and index variables. This data type is an unsigned integer. The reason for the unsigned integer data type for the seed variable is that the srand function requires an unsigned integer for input. The length 5 means that a value for the variable lies between 0 and  65535. Unsigned integer was also used for the index variable since the return value from rand is integer from 0 to 32767.

 

Perhaps you noticed the use of the keyword VALUE in the Set_Random prototype. This is important. When passing parameters to another procedure, RPG IV normally uses a technique called passing by reference, which means that a pointer address is used. The C language uses a parameter-passing technique called passing by value. In this scheme, the actual value of the parameter is passed. The RPG IV language can accommodate the C language requirement by using the keyword VALUE on the parameter to be passed.

 

In addition to srand and rand C functions, there are APIs available that will also provide random numbers, with larger values.

 

There is another C function that you will find interesting and time-saving when the need arises. I am referring to the C function strtok. The function name means string-token. It is used to parse character strings into their token components. A token is considered to be a character string up to a delimiter. If the strtok function is used with the string “See Spot run,” and a blank (space) is specified as the delimiter

character, then you would get “See” with one pass, “Spot” with a second pass, and “run” with the third pass. The return value for this function is a pointer to the token. When a return value of null is received, then no more tokens are available.

 

For an example, I will use a real-life situation in which a data conversion required changing a name field that included all portions of a name, such as Mr. John Q. Jones, into separate field components of title, first name, middle initial, and last name. This task had already been done using RPG opcodes of scan, check, and subst. However, once I was familiar with strtok, I wanted to see how this task could be done using the C function.

 

First, here is the prototype to the C function:

 

d GetToken        pr              *   ExtProc('strtok')

d  BigName                        *   Value Options(*String)

d  Delimit                        *   Value Options(*String)

 

There are lots of pointers here! The return value is a pointer to the token, or null. The two parameters are pointers to the big name and the delimiter fields. Also keywords VALUE are used since C uses passing by value, and the OPTIONS (*String) is used to have a null value appended to our character strings. C works with character strings as a single dimension array, with a null character at the end.

 

Not seen in the next section of code is the field FullName, which exists in the physical file. It is the field that contains the full name, including the title, first name, middle initial, and last name. Here are some work fields needed for this program.

 

d artok           s                   like(Fullname) dim(30)

d Token           s                   Like(FullName)

d ReturnAdr       s               *

d count           s              5u 0

d Space           c                   ' '

There are other work fields not shown here because they are not related to the parsing routine.

 

First, set up a data file read loop.

 

/free

Dou %eof(File1);

Read File1;

If %eof(File1);             // End of file – leave Do loop

Leave;

Endif;

 

Now, clear the output fields and work fields:

 

Clear Title;

Clear FirstName;

Clear Initial;

Clear LastName;

Clear artok;

Clear count;

 

Then, check for the all-blank name possibility:

 

// Not at end of file

If FullName = *blank;       // If Name is all blank –

Iter;                     // Get next file record

Else;

 

Next, since we now have a non-blank name, possible leading blanks are removed (as setup to the strtok function coming next):

 

FullName = %triml(Fullname);   // Remove leading blanks

ReturnAdr = GetToken(FullName:Space);   // Get first token

Dow ReturnAdr <> *Null;       // Load Tokens into Artok array

Token = %str(ReturnAdr);    // From null terminated to normal

Count += 1;                 // Count for array index

Artok(count) = %trim(Token);  // Put the token into the array

ReturnAdr = GetToken(*Null:Space); // Get next token

Enddo;  // The *Null above means continue where you left off

 

From here on, the processing is to place the array elements into the correct field: title, first name, middle initial, or last name. The count field is quite valuable in knowing how many total tokens were found in the full name field and then what to do with each array element.

 

The use of the strtok C function makes parsing a long string very easy to do.

 

The two examples above are meant to show you that interfacing with C functions can provide some capabilities that are useful to you as an RPG IV programmer. On the rare occasion when trigonometry or other higher math is needed, the appropriate C function can make overall programming much easier.

Other Functions?

This article contains excerpts from my new book, Functions in Free-Format RPG IV. Also explained in this book are the RPG IV built-in functions, subprocedures coded as functions, prototypes, and ILE concepts.

 

We are entering a new phase in our coding of RPG IV, writing smaller programs and using ILE to provide procedure interconnectivity and good performance. We are writing reusable routines as subprocedures and placing them in service programs. And we are using coding standards. If you cringed on that last statement, check out Appendix A of the book for some suggestions on coding standards. This is an exciting new era for RPG. Have fun!

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: