As mentioned previously, some human-readable text, followed by the CR and LF characters, will be viewed as a line of text. Consider the following code snippet:
D CRLF C const(x'0d25') D text S 14a c eval text = 'Hello there.' + CRLF
If I whip out my handy-dandy EBCDIC chart, I see that x'0D' is the EBCDIC code for carriage return, and x'25' is the EBCDIC code for line feed. Therefore, the variable called "text" above contains one line of text.
Consider this, more complicated, example:
D CRLF C const(x'0d25') D text S 500 c eval text = 'Hello there.' + CRLF + CRLF + c 'Nice day for a cruise.' + CRLF + c 'Maybe I''ll buy a yacht!'
Think about this: How many lines are stored in the variable called "text", above? Be careful before you answer, it's a trick question.
The answer is three and a half. Why? The first CRLF ends the first line, so the first line will read "Hello there!" in the text file. The next line ends when we encounter the next CRLF, which happens right away! That means the second line is blank. The third line says "Nice day for a cruise." and ends with another CRLF. The rest of the text, however, does not end with a CRLF. It's just part of a line.
All we have to do to put that text into a text file is call write(). This code would do the job:
c callp write(fd: %addr(text): c %len(%trimr(text)) )
One small problem: If we let it be written like this, our text file would be invalid. Why? Because, remember, we left off the CRLF at the end of the last line.
To make sure that we don't make that mistake again, why not create some helper routines? What we'll do is create a service program, called IFSTEXTR4 and put our text file routines into it. Then, we'll use it for all the text files we write.
The routine to write a line will be simple. All it needs to do is accept parameters (just like write() does) for the descriptor, the text, and the text length. Then, we'll just stick a CRLF into the file after that.
Here's our IFSTEXTR4 service program, with the writeline() procedure:
** Service program to assist in creating TEXT files in the IFS ** H NOMAIN OPTION(*NOSHOWCPY: *SRCSTMT) D/copy ifsebook/qrpglesrc,ifsio_h D/copy ifsebook/qrpglesrc,ifstext_h *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * The concept here is very simple: * 1) Write the data passed to us into the stream file. * 2) Add the end of line characters. *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ P writeline B export D writeline PI 10I 0 D fd 10I 0 value D text * value D len 10I 0 value D rc1 S 10I 0 D rc2 S 10I 0 D eol S 2A C* write the text provided c if len > 0 c eval rc1 = write(fd: text: len) c if rc1 < 1 c return rc1 c endif c endif C* then add the end-of-line chars c eval eol = x'0d25' c eval rc2 = write(fd: %addr(eol): 2) c if rc2 < 1 c return rc2 c endif c return rc1 + rc2 P E
And then, we'll also need a prototype. That's what the /copy line for the "IFSTEXT_H" member is for. We'll put our prototypes in that member, so they can be easily accessed from other programs.
Here's the IFSTEXT_H member, so far:
/if defined(IFSTEXT_H) /eof /endif /define IFSTEXT_H D writeline PR 10I 0 D fd 10I 0 value D text * value D len 10I 0 value
Don't compile it, yet! We're also going to add a routine for reading text files.