Quiz teaches 3000 CCTL carriage control
March 29, 2006
The HP 3000 has Carriage Control (CCTL) capabilities that can come in handy when formatting output from aged legacy applications. Robelle's SMUG Book entry says that CCTL
is the process of moving the print position (or "carriage") to the next line or page, as well as performing advanced functions such as overprinting and printing through the perforation. Normally the program specifies the CCTL code for a line through the Fwrite intrinsic. MPE has too many ways to do CCTL and modern printers are controlled via Postscript or Printer Command Language (PCL) anyway.
But CCTL has its users, and understanding how it works can be a key to resolving print problems with some of those aging applications you might have under your wing. Dave Powell wrote up a quiz on CCTL behavior recently, one he shared with the 3000 community. He explained some nuances in his article, one he researched as part of his ongoing CCTL-to-Rich Text Format (RTF) utility.
By Dave Powell
Start with a simple program that generates a 132-column, fixed length report. Run it with output to a spool file, like:
file rptfile; dev=lp,1
run progname
Then run it with output to a permanent cctl file, like:
file rptfile = permfile, new; dev=disc; cctl; save &
; rec=,32,f,ascii; disc=60000,32,0
run progname
Finally send the perm file to a spool file, like:
file newspool; dev=lp,1; cctl
print permfile > *newspool
Questions
1: Are the two spoolfiles identical ?
2: What about the printouts ?
Answers:
1: The spool files should be identical except for trailing blanks. The first spoolfile has all 133-column records for the actual report output (plus special zero-length records at the beginning and end). The second file may have some shorter records because trailing blanks have magically disappeared. So, the second may be much smaller, and will look more like a “real” variable length file. Check the file size with:
calc finfo(“o###.out.hpspool”,”bytefilesize”).
Just because spool files are ‘variable’ doesn’t mean anything eats blanks your app sends. But :print seems to eat them. Test “:print SomeFixedAsciiFile > NewTempFile” without any file equations, and see what it builds.
The non-spool file created the second time the program runs has all 133-column records, because omitting the record size in the file-equation causes the rec-len to be picked up from the program.
2: What printouts? The out-pri is 1. Well, besides that... the printouts will appear identical, unless your eyesight is good enough to spot trailing blanks on paper :)
Most of our big print jobs happen this way -- works like a charm.
Powell has a command file available that reports info on a CCTL file -- the CCTL code, the first few bytes of the data, and the record length.
This command file shows an HP CCTL report file's CCTL codes. :printspf may be better for spool files, because it shows the p1 and p2 fields.
Parms:
1: File name to read (must be cctl type, can be spool or not)
2: max number of records to read, even if the file is longer. Its SLOOOOW, so use this.
For each line of the input file, it shows:
• Line #
• Carriage control code, if any, in decimal, octal and my description of the meaning. Different codes that have the same effect may have different descriptions.
• The beginning of the data part of the record, padded or truncated to 16 bytes.
• The total record length (including the cctl byte). Spoolfiles will have records with ZERO length, hence no cctl code. The 0-len records at the start and end have open and close commands in the function word of the hidden area. See :printspf and Appendix A of the Native Mode Spooler Manual.
parm _from = ""; _limit = 200
parm entry = 'main'
option nolist
if "!entry" = "main" then
if bound (X_ERRORS)
deletevar X_@
endif
setvar X_ERRORS 0
if fsyntax('!_from')<>"MPE" and fsyntax('!_from')<>"POSIX"
setvar X_ERRORS X_ERRORS + 1
echo Parm-1 (file name to convert FROM) is required
echo and must be a valid file name.
endif
if len ("!_limit") < 1 or not numeric ("!_limit")
setvar X_ERRORS X_ERRORS + 1
echo Invalid limit on #-of-records to read
echo If not omitted, 2nd-parm must be a positive integer
endif
if X_ERRORS > 0
showvar X_@
return
endif
setvar X_FROM '!_from'
file XFROM = !X_FROM, OLD; CCTL
if not finfo('*XFROM','EXISTS')
echo No such permanent file as "!X_FROM"
setvar X_ERRORS X_ERRORS + 1
else
setvar X_EOF finfo('*XFROM','EOF')
if X_EOF < 2
echo File '!X_FROM' does not have enough records
setvar X_ERRORS X_ERRORS + 1
endif
endif
if X_ERRORS > 0
echo Old file '!X_FROM' cannot be processed
echo format.
showvar X_@
return
endif
setvar X_LIMIT min (X_EOF, !_LIMIT)
xeq !hpfile entry = ReadLoop < *XFROM
if X_ERRORS = 0
echo Done OK
else
showvar X_@
endif
return
elseif "!entry" = "ReadLoop"
echo Line Cctl-code Data RecLength
setvar X_CNT 0
while setvar (X_CNT, X_CNT+1) <= X_LIMIT do
input X_REC
setvar X_CNT_ RHT (' !X_CNT',4)
setvar X_LEN LEN (X_REC)
if X_LEN > 0
setvar X_CCTL LFT(X_REC,1)
setvar X_ORD ORD (X_CCTL)
setvar X_ORD__ "!X_ORD"
setvar X_OCT__ "![OCTAL(X_ORD)]"
if X_ORD >= 128 and X_ORD <= 192
setvar X_DESC "Adv" + "![X_ORD - 128]"
elseif X_ORD >= 2 and X_ORD <= 42
setvar X_DESC "SingleSp"
elseif X_ORD >= 192 and X_ORD <= 207
setvar X_DESC "VFC code"
elseif X_ORD = 49 or X_ORD = 51
setvar X_DESC "CondEject"
elseif X_ORD = 0
setvar X_DESC "Single"
elseif X_ORD = 45
setvar X_DESC "Triple"
elseif X_ORD = 48
setvar X_DESC "Double"
elseif X_ORD = 64
setvar X_DESC "PostSp"
elseif X_ORD = 65
setvar X_DESC "PreSpace"
elseif X_ORD = 67
setvar X_DESC "NoAutoPage"
elseif X_ORD = 208
setvar X_DESC "NoSpNoRet"
else
setvar X_DESC " "
endif
else
setvar X_CCTL '*NONE*'
setvar X_ORD 0
setvar X_DESC "{none}"
setvar X_ORD__ " "
setvar X_OCT__ " "
endif
if X_LEN > 1
setvar X_DATA str (X_REC+rpt(" ",16), 2, 16)
setvar X_DATA__ repl (X_DATA, ">", "!>")
else
setvar X_DATA " "
setvar X_DATA__ rpt (" ", 16)
endif
echo ![RHT (" !X_CNT", 4)];&
![RHT (" !X_ORD__", 4)] &
![RHT (" "+X_OCT__, 5)] &
![LFT ("!X_DESC ", 10)];&
![X_DATA__];&
![RHT (" !X_LEN", 4)]
deletevar X_REC
endwhile
return
##- just one more error-check
else
setvar X_ERRORS X_ERRORS + 1
echo Error - invalid entry point
showvar X_@
return
endif
return