29
Fri, Nov
0 New Articles

Word Wrap Utility

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

OK, all you green-screen programmers out there, listen up! Today, we're going to discuss the dark cloud that hangs over all of your text-based applications. You know the ones I mean. They're the ones that rain broken words all across an otherwise-professional-looking program. When this storm breaks, it can destroy the appearance of a screen or document and cause the entire context of a phrase to change. For example, the sentence, "You are a doggedly persistent employee" could easily become, "You are a dog" when a word is broken inappropriately across two lines. Imagine reading that on your annual review!

This is the sort of thing PC programmers easily avoid by using common word wrap routines in their applications, something you probably thought would never be available to you. However, no longer is the word wrapping function confined to the PC world. Now, it is available for use with 5250 sessions, too.

This utility can be called from any application in which you need to equip a user with the ability to enter free-form text. When the word wrapper runs, it overlays your application's screens with a window that contains a 10-line subfile. If you pass a character literal to the program for the title, it is centered in the top of the window. At the bottom of the window, a counter keeps track of the current cursor page and line position.

With this function, your users can do real heads-down text entry, since they no longer need to worry about unnatural word breaks or need to press the field exit or Enter key to move to the next line. When they have filled 10 subfile lines, the screen automatically rolls to the next page, positioning the cursor correctly, even if the word wrapper must take the last word typed from the previous page and place it as the first word on the new page. When the user is finished with text entry, he simply presses the F3 key to end the program, which passes the formatted text back to the calling application. From there, your program can load the contents of the returned array into a database file, using the numeric counter passed back to your program to determine the number of times to loop through it. Now, you can print this data on a report or display it on a screen, and it will be perfectly formatted every time.

This utility consists of CLP program WW000C1 (Figure 1), display file WW000D1 (Figure 2), and RPG program WW000R1 (Figure 3). CLP program WW000C1 is included here merely to demonstrate how to call the RPG program and to provide you with a working example that you can use to try out the tool before you integrate it into your applications. In actual practice, you would probably embed the call to WW000R1 within another RPG or COBOL program.

When your application calls the word wrapper program WW000R1 (Figure 3), it will need to pass the program three parameters: an array 50 bytes long with 150 elements, a character string with a length of 56 characters, and a 15-digit packed-decimal field with five decimal places. The first parameter can be empty, or it can be loaded, prior to calling the word wrapper tool, with previously entered text if you want that text to be redisplayed. The second parameter can contain any text you want centered at the top of the word wrapper window to identify the content of the text being typed or displayed. The third parameter is used two ways: If this is the first call to the word wrapper from your application and the first parameter is empty, this field should be passed as a value of 1. If you are passing text to the word wrapper from some previous call, this field will contain the number of elements you are passing to the word wrapper program. In addition, when control returns to your program, this numeric field will contain the number of entries in the first parameter.

Some very ordinary housekeeping performed at program initiation performs the following:

o Centers any header text passed to it

o Clears and loads the subfile with any previously wrapped text you may have passed to this program

o Sets the cursor position in the footer of the word wrapper window

o Positions the cursor to the first row and column of the subfile window

Your user is presented with a window, overlaying the previous application, that contains a centered header that describes the content of the text he will type. In addition, if he has previously keyed anything for this particular record, that text will also be shown. If not, he will see 10 blank subfile lines upon which he may begin to enter data.

The CHECK(LC) and CHECK(ER) keywords are used on the subfile lines to allow the use of lowercase character entry and automatic record advance. When the cursor comes to the end of the line, that subfile line is read and its contents moved to the corresponding element of the input/output array TXT. It is at this point that the line is scrutinized to see if word wrapping should be performed.

The logic used to perform the word wrapping function is quite simple. It consists of some very ordinary RPG string operations. When subroutine WRDWRP begins, it initializes some work variables, including clearing array FTX. This array is used as a work area to temporarily store the formatted text.

The first test is to make sure that the current subfile line read is not blank. If it is empty, the program bypasses the word wrapping logic entirely. Otherwise, the input/output array TXT is moved to work array FTX. The value in the FTX element that is equal to the currently active

subfile line is moved to work variable STRING, which is the same length as the subfile line. The program then clears the FTX array element it just moved to STRING so that the FTX array can later be overwritten with the formatted data.

The last blank position in STRING is located by using the CHEKR op code, and that value is stored in R. I then search for the last nonblank position and store that value in variable LSTCHR. If the last nonblank character found is equal to the values of RMINS1 or ROWLEN, I want to reset the value in LSTCHR to be ROWLEN minus the position of the last blank position. This step is required to ensure that the word wraps properly when it begins in one of the last two positions on the line.

If there are characters at the end of the line, they need to be moved, or wrapped, to the next line. This is done by substringing the characters in variable STRING, beginning at the first position of the line and extending to the last blank position. (This is the reason for locating the last blank position earlier.) This substringed value is placed in work array FTX at the current element. If any characters did not get moved to FTX in that last operation, they are substringed into the first position of the next element of FTX. The number of characters to substring into that element is determined by subtracting from ROWLEN the value of the position of the last blank position from the previous line (the length of the subfile line). This formula gives the length of the number of characters to substring. That value is then subtracted from the value in RPLUS1 (the length of the subfile line plus 1). This is the position in variable STRING in which the characters that need to be moved to the next line begin. This information is then used to substring those characters into FTX at the next element. Finally, array FTX is moved to array TXT.

All that's left to do is build the footer literal to show the current cursor page and line position and to reposition the cursor and subfile page. The first part is accomplished by dividing the current active subfile line number by 10 (size of the subfile page) and adding 1 to it to get the next line number. The subfile record number is also incremented at this point. This new line number is then used in subroutine CURPOS along with some simple concatenation to build the footer literal.

Determining the next cursor position and positioning it to the correct subfile page is achieved by evaluating the current active subfile line. The line number is moved to a one-position numeric variable. If this value is 0, this is the last line of the 10-line subfile, so the cursor should be positioned on the first line of the next page. If it is anything other than 0, the cursor row position is incremented by 1. This positions the cursor on the correct line. To move it to the correct column, I add the value in LSTCHR (where I stored the last nonblank position of the previous line) to RELCOL (the relative position on the screen of the beginning of the subfile line) to get the new column number. This positions the cursor on the next column after the last character typed, even if that character was the last character on the previous line.

There are two final things to be aware of: First, the display file for the word wrapper window should be compiled with RSTDSP(*YES). You may or may not need to do the same with the display used by the calling application. You'll have to experiment with that.

Second, you should have the Typeahead (keyboard buffering) function turned on. Keyboard buffering can take one of two forms: *TYPEAHEAD (which tells the system to turn on the keyboard type ahead feature but not the Attention Key buffering) or *YES (which turns on both).

You can turn the function on by one of three methods:

o For the entire system, set system value QKBDBUF, specifying either *TYPEAHEAD or *YES.

o For individual user profiles, use the Change User Profile (CHGUSRPRF) command, setting parameter KBDBUF to either *TYPE- AHEAD or *YES.

o For the job level, call API QWSSETWS, passing it a parameter of 1 (which is the same as *TYPEAHEAD in the other options) or 2 (which is the same as *YES in the other options).

You can modify the size of the values used in this program. However, if you decide to change these values, you should be aware of the following:

Any reference to the length of the subfile line, which is currently 50, will need to be modified if you change it. This includes the arrays TXT, FTX, and variable STRING. For convenience, variables ROWLEN, RPLUS1, and RMINS1 are initialized with the values of 50, 51, and 49 in the INIT subroutine and then referenced throughout the text to determine row length, row length plus one, and row length minus one.

If you increase or decrease the number of elements in the input/output array TXT, you will also need to reflect those changes in array FTX, as well as change the subfile size parameter in the accompanying DDS. You should also be aware that the logic for determining the next cursor row is based on a 10-line subfile. If you change the size of the subfile page, you must modify this area as well.

If you change the column or row where the subfile is displayed, you must modify variables RELROW and RELCOL. Currently, these values are initialized at 11 and 15 in the INIT subroutine.

Indicator 03 is an arbitrary choice on my part to use for updating the text and closing out the program. You could easily expand this functionality by adding separate indicators for updating, deleting, and exiting.

That's it! Wasn't that simple? OK then, it's time for you to get this tool into production and start basking in the praise that will be heaped upon you by a multitude of satisfied users. You will no longer have to hide in your cubicle because your users' text looks like someone chopped it up with scissors. Now, you can finally walk to the break room for coffee with your head held high, instead of waiting till everyone else in the building has gone to a meeting.

Shannon O'Donnell is a technical editor for Midrange Computing and a senior consultant with Computer Application Solutions, Inc. in Springfield, Illinois. He can be reached at This email address is being protected from spambots. You need JavaScript enabled to view it..

Figure 1: CLP program WW000C1 shows how to pass the 550 X 50 byte array and title to the utility

/*==================================================================*/

/* To compile: */
/* CRTCLPGM PGM(XXX/WW000C1) SRCFILE(XXX/QCLSRC) */
/* */
/* This CL is used as an example of how to call the Wordwrap Tool. */

/*==================================================================*/

PGM

DCL VAR(&TXT) TYPE(*CHAR) LEN(7500)
DCL VAR(&HDRLIT) TYPE(*CHAR) LEN(56) VALUE('Word +

Wrap Utility')
DCL VAR(&CNTR) TYPE(*DEC) LEN(15 5) VALUE(1)

CALL PGM(WW000R1) PARM(&TXT &HDRLIT &CNTR)

ENDPGM A*****************************************************************
A* To Compile:
A* CRTDSPF FILE(XXX/WW000D1) SRCFILE(XXX/QDDSSRC) RSTDSP(*YES)
A*****************************************************************
A DSPSIZ(24 80 *DS3)

A CF03(03 'EXIT/SAVE')
A PRINT
A R S1SFL SFL
A TEXT 50A B 11 15CHECK(ER)

A CHECK(LC)
A11 12' '

A DSPATR(RI)
A11 67' '

A DSPATR(RI)
A R C1SFL SFLCTL(S1SFL)
A SFLSIZ(0150)
A SFLPAG(0010)
A 82 SFLDSP
A 81 SFLDSPCTL
A 80 SFLINZ
A SFLCSRRRN(&SRRN)
A CSRLOC(XROW XCOL)
A OVERLAY
A RECPOS 4S 0H SFLRCDNBR(CURSOR)
AXROW 3S 0H
AXCOL 3S 0H
ASRRN 5S 0H
A HDRTXT 56 O 10 12DSPATR(RI)

A R C1FTR
A OVERLAY
A FTRTXT 56 O 21 12DSPATR(RI)
A R DUMMY
A ASSUME
A DMYFLD 1A B 2 2DSPATR(PR) *****************************************************************

*

* To Compile: CRTRPGPGM PGM(XXX/WW000R1) SRCFILE(XXX/QRPGSRC)
*

*****************************************************************

FWW000D1 CF E WORKSTN
F RRN KSFILE S1SFL

*E TXT 150 50 Input Text To FMT
E FTX 150 50 Formatted Text
E HC 56 1 Header Text Cntrd
E HU 56 1 Header Txt Uncntd
*I 'ABCDEFGHIJKLMNOPQRS- C VC
I 'TUVWXYZabcdefghijkl-
I 'mnopqrstuvwxyz01234-
I '567890`!@#$%^&*()_I

Figure 2: Display file WW000D1 is the pop-up window

Figure 3: RPG program WW000R1 is the word wrap window driver and word wrap utility all in one

SHANNON ODONNELL
Shannon O'Donnell has held a variety of positions, most of them as a consultant, in dozens of industries. This breadth of experience gives him insight into multiple aspects of how the AS/400 is used in the real world. Shannon continues to work as a consultant. He is an IBM Certified Professional--AS/400 RPG Programmer and the author of an industry-leading certification test for RPG IV programmers available from ReviewNet.net.
 
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: