#!/bin/sh # # This is a shell archive. To extract its contents, # execute this file with /bin/sh to create the file(s): # # rptfuncs.awk rptfuncs.doc rptsample1.awk rptsample2.awk # # This shell archive created: Fri Sep 6 14:01:59 EDT 1996 # echo "Extracting file rptfuncs.awk" sed -e 's/^X//' <<\SHAR_EOF > rptfuncs.awk X# rptfuncs.awk X# X# X# SCCS ID: @(#) rptfuncs.awk 1.2 8/26/96 15:53:27 X# X# (c) Copyright 1994 by Walt Hultgren. All rights reserved. X# X# X# Functions: X# X# start_report initialize report control & start report X# need account for lines about to be printed X# skip_to_top_of_page finish current page & move to top of next page X# finish_page finish current page & stop at bottom X# finish_report finish report by finishing current page if needed X# X# X X Xfunction start_report( arg_prtppg, arg_linppg, arg_hdrflg ) { X X rp_prtppg = arg_prtppg # printed lines/page including header X rp_linppg = arg_linppg # total lines/page for NLs, 0 for FFDs X rp_lincnt = 0 # current line count (lines printed) X rp_pageno = 1 # current page number X rp_hdrflg = 1 # ==> need header before next report line X rp_status = 0 # status return X X "date +%D" | getline rp_date # current date MM/DD/YY X "date +%T" | getline rp_time # current time HH:MM:SS X X if ( arg_hdrflg != 0 ) skip_to_top_of_page() X X return rp_status X } X X Xfunction need( arg_lines ) { X X if ( arg_lines > 0 ) X { X if ( rp_hdrflg == 1 || rp_lincnt + arg_lines > rp_prtppg ) X { X if ( skip_to_top_of_page() ) return rp_status X } X X rp_lincnt = rp_lincnt + arg_lines X } X X rp_status = 0 X X return rp_lincnt X } X X Xfunction skip_to_top_of_page() { X X if ( finish_page() ) return rp_status X X rp_status = page_header( rp_pageno ) X X if ( rp_status < 0 ) return rp_status X X rp_lincnt = rp_status X rp_hdrflg = 0 X X rp_status = 0 X X return rp_status X X } X X Xfunction finish_page() { X X if ( rp_lincnt > 0 ) X { X while ( rp_lincnt < rp_prtppg ) X { X print "" X ++rp_lincnt X } X X rp_status = page_trailer( rp_pageno ) X X if ( rp_status < 0 ) return rp_status X X rp_lincnt = rp_lincnt + rp_status X X if ( rp_linppg > 0 ) X { X while ( rp_lincnt < rp_linppg ) X { X print "" X ++rp_lincnt X } X } X else X { X printf( "%c", 12 ) X } X X rp_pageno = rp_pageno + 1 X X rp_lincnt = 0 X rp_hdrflg = 1 X X } X X rp_status = 0 X X return rp_status X X } X X Xfunction finish_report() { X X return finish_page() X X } SHAR_EOF if [ `wc -c < rptfuncs.awk` -ne 2495 ] then echo "Lengths do not match -- Bad Copy of rptfuncs.awk" fi echo "Extracting file rptfuncs.doc" sed -e 's/^X//' <<\SHAR_EOF > rptfuncs.doc Xrptfuncs.doc X X XThis file explains the use of the AWK functions found in "rptfuncs.awk", which Xsimulate some of the report control features of the Informix 4GL and ACE report Xfacilities. X XThese functions are based on C routines that were originally written to provide Xprograms containing Informix 3.30 ALL II calls with the same report control Xfunctionality found in ACE. They have since been ported to Informix-4GL as Xwell as to AWK. X XThis code is provided without any warranties, but I would like to hear of any Xbugs or problems you run into. Please send such reports to walt@rmy.emory.edu. X X XUSING THE FUNCTIONS X XThese functions perform only line counting and automatic pagination. They do Xnot attempt to inspect the data being printed and provide control breaks, Xgroup processing or other report generation features. X XEach function is named similar to its 4GL counterpart. The available functions Xare: X X start_report initialize report control & optionally print header X need account for lines about to be printed X skip_to_top_of_page finish current page & move to top of next page X finish_page finish current page & stop at bottom X finish_report finish report by finishing current page if needed X XTo use the report functions, you must supply the main body of the AWK report, Xplus two functions: page_header() and page_trailer(). X XTo initialize the report control parameters, call start_report() before any Xreport output is generated. This is often done in a BEGIN{} section of the XAWK program. X XAs you are about to print each group of one or more report lines, call the Xfunction need() with the number of lines about to be printed. This must be Xdone for all output lines, even if they are printed one at a time. If you want Xto keep a block of lines together on the same page, call need() with the total Xnumber of lines in the block before you print any of them as you would in 4GL Xor ACE. X XWhen all report output has been generated, call finish_report() to complete the Xlast page. This is usually done in an END{} section. X X XFUNCTIONS YOU SUPPLY X XYou must supply two report functions in addition to the other AWK code you Xwrite to generate the body of the report. X XThe page_header() function is called by the report functions to print a page Xheader whenever the report moves to the top of a new page. The page_trailer() Xfunction is called to print a page trailer at the bottom of each page. X XThese functions should not call need() prior to printing header or footer Xlines. Each function should return the number of lines it printed. X XNeither function has to generate any output, but both must be present. If Xeither of these functions does not print anything, it should return a value Xof (0) to indicate that no lines were printed. X XHeaders on different pages do not have to contain the same number of lines. XThis is also true for trailers. X XEach function is called with a single argument, which is the number of the Xcurrent page. That is, the functions are called by "page_header(pageno)" and X"page_trailer(pageno)". X X XRETURN VALUES X XThe convention for function return values is that (0) indicates success. A Xnegative value means a fatal error has occurred, and the report should be Xstopped immediately. Several functions return positive values in the course of Xnormal operation. These are also considered to indicate success, and are Xpassed back through the calling sequence. X X XGLOBAL VARIABLES X XThe report functions maintain a number of global variables to control the Xformat of the report: X X rp_prtppg desired number of header + body lines in report X rp_linppg total lines per physical page, or (0) to use form-feeds X rp_lincnt current line count (lines printed) X rp_pageno current page number X rp_hdrflg 1 ==> need header before next report line X rp_status status return X rp_date current date MM/DD/YY X rp_time current time HH:MM:SS X XThe date and time are set once by the function start_report(). They are not Xchanged automatically during the report run, though you may do so. X X XFUNCTION REFERENCE X XThis section lists the various report functions, along with their required Xarguments and return values. X X------------------------------------------------------------------------------ X X XFunction: page_header( pageno ) X X X This is the function you supply to print a header at the top of each page. X X XArguments: X X pageno The number of the current page. This value is kept in the global X variable rp_pageno. X X XReturn Value: X X negative Fatal error encountered. X X other Number of lines printed. X X XNotes: X X Do not call need() to account for lines printed in the header. X X------------------------------------------------------------------------------ X X XFunction: page_trailer( pageno ) X X X This is the function you supply to print a trailer at the bottom of each X page. X X XArguments: X X pageno The number of the current page. This value is kept in the global X variable rp_pageno. X X XReturn Value: X X negative Fatal error encountered. X X other Number of lines printed. X X XNotes: X X Do not call need() to account for lines printed in the trailer. X X------------------------------------------------------------------------------ X X XFunction: start_report( prtppg, linppg, hdrflg ) X X X This function is called to initialize the report control parameters and X optionally print a page header. X X XArguments: X X prtppg The number of lines to be printed on each page, including the X header, but *not* including the trailer; that is, this is the last X line of the body of the report. The trailer, if any, will start on X line (prtppg+1). X X This value is kept in the global variable rp_prtppg. X X linppg This is the total number of lines on a page; that is, the physical X page size. A very common value for this is 66 lines per page. X X If this value is a positive integer, the report functions will move X to the next page by printing the required number of blank lines. X If this value is zero (0), the functions will move to the next page X by outputting a form-feed (ASCII 12) character. X X This value is kept in the global variable rp_linppg. X X hdrflg This argument indicates whether you want to force a header X immediately when the report starts, or print a header only if there X is some report output. A value of (1) forces a header, while a X value of (0) causes the report to wait. X X If you specify (0) and no output is generated for the body of the X report (i. e., need() is never called), no output will be printed. X X XReturn Value: X X 0 Success. X X negative As returned from page_header() if a header is forced. X X XNotes: X X start_report() sets the value of the global variables rp_date and rp_time X by executing the system date command. X X------------------------------------------------------------------------------ X X XFunction: need( lines ) X X X Calling this function reserves room on the current page for the specified X number of lines. If there is not sufficient room on the current page, the X report functions automatically move to the next page. X X XArguments: X X lines The number of lines about to be printed. Zero (0) is a legal X value. X XReturn Value: X X This function returns the number of lines printed on the current page, X *including* the number of lines supplied in the call. X X To get the current line number without causing any other action, use X "need(0)". Another way of obtaining the current line count is from the X global variable rp_lincnt. X X Do not call this function from within page_header() or page_trailer(). X X------------------------------------------------------------------------------ X X XFunction: skip_to_top_of_page() X X X This function causes the report to move to the top of the next page and X print a page header. finish_page() is called to move to the bottom of the X current page, then page_header() is called to print a header on the next X page. X X XReturn Value: X X 0 Success. X X negative As returned from page_header() or page_trailer(). X X------------------------------------------------------------------------------ X X XFunction: finish_page() X X X This function finishes the current page. X X XReturn Value: X X 0 Success. X X negative As returned from page_trailer(). X X XNotes: X X When this function is called, it first issues enough blank lines to complete X the total number of header/body lines on the page supplied as the first X argument to start_report() and kept in rp_prtppg. X X It then calls page_trailer() to print any page trailer, and adds the trailer X line count to the current line count. X X The function then moves to the bottom of the current page. If the physical X page size (kept in rp_linppg) is a positive line count, finish_page() will X print blank lines to complete the page if needed. If the trailer exactly X finishes the page, no action will be taken. X X If the physical page size is zero (0), then finish_page() will ouput a X form-feed character (ASCII 12). This will happen whether the trailer exactly X fills the page or not. X X------------------------------------------------------------------------------ X X XFunction: finish_report() X X X This function is called to finish the report, usually from an END{} section X in the AWK program. X X XReturn Value: X X 0 Success. X X negative As returned from page_trailer(). X X XNotes: X X In its present form, all finish_report() does is call finish_page(). This X function is supplied since most 4GL programmers are accustomed to executing a X FINISH REPORT statement to complete a report. X X------------------------------------------------------------------------------ X XEnd of rptfuncs.doc SCCS ID: @(#) rptfuncs.doc 1.2 2/17/94 13:32:57 X X(c) Copyright 1994 by Walt Hultgren. All rights reserved. SHAR_EOF if [ `wc -c < rptfuncs.doc` -ne 9989 ] then echo "Lengths do not match -- Bad Copy of rptfuncs.doc" fi echo "Extracting file rptsample1.awk" sed -e 's/^X//' <<\SHAR_EOF > rptsample1.awk X# rptsample1.awk Report to list Login-ID's X# X# X# Usage: sort /etc/passwd | nawk -F: -f rptsample1.awk -f rptfuncs.awk X# X# or: cat rptsample1.awk rptfuncs.awk > temp.awk X# sort /etc/passwd | nawk -F: -f temp.awk X# X# X# This report prints a list of login-ID's, with a blank line after every X# fifth output line for easier reading. X# X# X# SCCS ID: @(#) rptsample1.awk 1.2 2/17/94 13:33:40 X# X# (c) Copyright 1994 by Walt Hultgren. All rights reserved. X# X# X X XBEGIN { X X start_report( 60, 66, 1 ) # force header so need(0) is right on 1st record X } X X{ X cur_line = need(0) X X if ( cur_line != 60 && (cur_line - 6) % 6 == 0 ) { need(1) ; print "" } X X need(1) X printf ( "%-8s %7s %-26s %-30s\n", $1, $3, $5, $6 ) X } X X XEND { X X need(2) X X print "" X print "Total of " NR " Login-ID's listed." X X finish_report() X } X X Xfunction page_header(pageno) { X X printf " " X print "Login-ID Listing" X X printf "%-8s %64s %3d\n", rp_date, "Page", pageno X X print rp_time X X print "" X X printf "Login-ID User-ID Name " X print " Home Directory" X X printf "-------- ------- --------------------------" X print " ------------------------------" X X print "" X X return 7 X } X X Xfunction page_trailer(pageno) { X X return 0 X } SHAR_EOF if [ `wc -c < rptsample1.awk` -ne 1355 ] then echo "Lengths do not match -- Bad Copy of rptsample1.awk" fi echo "Extracting file rptsample2.awk" sed -e 's/^X//' <<\SHAR_EOF > rptsample2.awk X# rptsample2.awk Report to list Login-ID's X# X# X# Usage: sort /etc/passwd | nawk -F: -f rptsample2.awk -f rptfuncs.awk X# X# or: cat rptsample2.awk rptfuncs.awk > temp.awk X# sort /etc/passwd | nawk -F: -f temp.awk X# X# X# This report prints a list of login-ID's. A preceding blank line is output X# every time the first character of the login-ID's changes, unless a new X# page is about to be started or has just started. X# X# X# SCCS ID: @(#) rptsample2.awk 1.2 2/17/94 13:33:55 X# X# (c) Copyright 1994 by Walt Hultgren. All rights reserved. X# X# X X XBEGIN { X X start_report( 60, 66, 1 ) # force header so need(0) is right on 1st record X X cur_char = " " X } X X{ X if ( index( $1, cur_char) != 1 ) X { X cur_line = need(0) X X if ( cur_line != 7 && cur_line != 60 ) X { X need(1) X print "" X } X X cur_char = substr( $1, 1, 1) X } X X need(1) X printf ( "%-8s %7s %-26s %-30s\n", $1, $3, $5, $6 ) X } X X XEND { X X need(2) X X print "" X print "Total of " NR " Login-ID's listed." X X finish_report() X } X X Xfunction page_header(pageno) { X X printf " " X print "Login-ID Listing" X X printf "%-8s %64s %3d\n", rp_date, "Page", pageno X X print rp_time X X print "" X X printf "Login-ID User-ID Name " X print " Home Directory" X X printf "-------- ------- --------------------------" X print " ------------------------------" X X print "" X X return 7 X } X X Xfunction page_trailer(pageno) { X X print "" X print "" X X printf " " X print "** Proprietary and Confidential - Restricted Distribution **" X X return 3 X } SHAR_EOF if [ `wc -c < rptsample2.awk` -ne 1721 ] then echo "Lengths do not match -- Bad Copy of rptsample2.awk" fi echo "Done." exit 0