From infmx!johnl Fri Jul 24 09:16:48 1992 Date: Fri, 24 Jul 92 13:30:21 GMT From: emory!widener!obelix.informix.com!johnl (Jonathan Leffler) Message-Id: <9207241330.AA20068@obelix.informix.com> To: informix-list@rmy.emory.edu Subject: INFORMIX-4GL Dynamic Report Output Parameters Version 2 Cc: mbp@nyssa.wa7ipx.ampr.org X-Informix-List-Id: Some time ago, I lobbed some C code at the net which adapted the output dimensions of an I4GL report at runtime, with the comment that I hadn't got it to work with I4GL-RDS. On 29th April 1992, Marlin Prowell put an adapted version of my code on to the net, having made it work under I4GL-RDS. The shell archive below is an integrated version of our two efforts: there is a compile line parameter -DI4GL_RDS required to make it work under I4GL-RDS and no parameter for compiled I4GL (I4GL-C?). There is also an updated manual page, and some example I4GL code which is used in the manual page. I hope you find this useful. Marlin: thanks for the effort -- it was a great help. And for the fix in the code. I've kept your comments in the code. Jonathan Leffler (johnl@obelix.informix.com) #include FYI: I didn't cheat and look at the source code for the Informix products. : "@(#)shar.sh 1.8" #! /bin/sh # # This is a shell archive. # Remove everything above this line and run sh on the resulting file. # If this archive is complete, you will see this message at the end: # "All files extracted" # # Created: Fri Jul 24 11:43:14 GMT 1992 by johnl at Informix Software Ltd. # Files archived in this archive: # report.man # report.c # rejig.4gl # #-------------------- if [ -f report.man -a "$1" != "-c" ] then echo shar: report.man already exists else echo 'x - report.man (4043 characters)' sed -e 's/^X//' >report.man <<'SHAR-EOF' X'\" @(#)report.man 1.4 92/07/24 X'\" @(#)Manual page: General Library -- Report Configuration X.ds fC "report.man 1.4 92/07/24 X.TH REPORT 3S "JLSS Informix Tools" X.SH NAME Xset_output \(em Dynamically reconfigure dimensions of I4GL report X.SH SYNOPSIS X.ft B Xfunction set_plength(i) X.br Xdefine i integer X.sp Xfunction set_tmargin(i) X.br Xdefine i integer X.sp Xfunction set_bmargin(i) X.br Xdefine i integer X.sp Xfunction set_lmargin(i) X.br Xdefine i integer X.sp Xfunction set_rmargin(i) X.br Xdefine i integer X.sp Xfunction set_output() X.ft R X.ft B Xfunction get_plength() X.sp Xfunction get_tmargin() X.sp Xfunction get_bmargin() X.sp Xfunction get_lmargin() X.sp Xfunction get_rmargin() X.ft R X.SH DESCRIPTION XThese functions can be used to dynamically reconfigure the layout Xof the page of an Informix 4GL report. XThe example program shown below illustrates how they should be used. X.br X.ft CW X.ps 10 X.vs 12 X.nf X.so rejig.4gl X.br X.fi X.ft X.ps X.vs XThe functions \fIset_plength\fP, \fIset_tmargin\fP, X\fIset_bmargin\fP, \fIset_lmargin\fP and \fIset_rmargin\fP may be called Xanywhere inside an I4GL program. XThe function \fIset_output\fP will have no effect except within a report. XIt is recommended that \fIset_output\fP be used in the \s-2FIRST XPAGE HEADER\s0 control block, but it may be used in any control block. X.P XAfter the function \fIset_output\fP is called, it invalidates all the settings; Xto change the settings in a second report, you must call the Xset-routines again. XThere is no requirement that all the routines are called (or even any of them). X.P XThe functions \fIget_plength\fP, \fIget_tmargin\fP, X\fIget_bmargin\fP, \fIget_lmargin\fP and \fIget_rmargin\fP may be called Xanywhere inside an I4GL program. XIf page dimensions have been set using the set-routines, then the corresponding Xvalue is returned; otherwise, the corresponding default value is returned. XAfter \fIset_output\fP has been called, the values returned will be Xthe default values again; if your report needs to know what its dimensions will Xbe, it should use the get-routines before calling \fIset_output\fP. X.SH COMPILATION XIf compiling for use with compiled Informix-4GL, no special flags are needed. XIf compiling for use with I4GL-RDS, include -DI4GL_RDS on the command line. XThe details of building the functions into the \*Cfglgo\*D Xand \*Cfgldb\*D are given in the corresponding Informix manuals. XThe necessary definitions for \*cfgiusr.c\*d are: X.br X.ft CW X.ps 10 X.vs 12 X.nf X#ifdef SET_REPORT Xextern int set_output(); /* 0 */ Xextern int get_rmargin(); /* 0 */ Xextern int get_tmargin(); /* 0 */ Xextern int get_bmargin(); /* 0 */ Xextern int get_lmargin(); /* 0 */ Xextern int get_plength(); /* 0 */ Xextern int set_rmargin(); /* 1 */ Xextern int set_tmargin(); /* 1 */ Xextern int set_bmargin(); /* 1 */ Xextern int set_lmargin(); /* 1 */ Xextern int set_plength(); /* 1 */ X#endif /* SET_REPORT */ X X#ifdef SET_REPORT X { "set_output", set_output, 0 }, X { "get_rmargin", get_rmargin, 0 }, X { "get_tmargin", get_tmargin, 0 }, X { "get_bmargin", get_bmargin, 0 }, X { "get_lmargin", get_lmargin, 0 }, X { "get_plength", get_plength, 0 }, X { "set_rmargin", set_rmargin, 1 }, X { "set_tmargin", set_tmargin, 1 }, X { "set_bmargin", set_bmargin, 1 }, X { "set_lmargin", set_lmargin, 1 }, X { "set_plength", set_plength, 1 }, X#endif /* SET_REPORT */ X.br X.fi X.ft X.ps X.vs X.SH WARNINGS XThis code was designed and tested on an ATT&T 3B2/400 running XUNIX System V Release 3.0 using Informix-4GL version 1.10.00C. XIt has since been tested on a number of other environments (including Versions X1.10.03, 4.00 and 4.10) on a number of platforms, and has been found to work. XHowever, the code cannot be guaranteed on any platform or version of I4GL. XIt is completely unsupported code. X.SH BUGS XThe top margin set by \fBset_tmargin\fP does not take effect Xuntil the second page of output. X.SH AUTHOR XJonathan Leffler X.br XMarlin Prowell X.br XJLSS X.br X24th July 1992 SHAR-EOF chmod 444 report.man if [ `wc -c report.c <<'SHAR-EOF' X/* X@(#) File: report.c X@(#) Version: 2.1 X@(#) Last changed: 92/07/24 X@(#) Purpose: I4GL: Reset report output parameters (RDS & C4GL) X@(#) Author: J Leffler / M Prowell X*/ X X/*TABSTOP=4*/ X X/* X** INFORMIX-4GL Dynamic Report Output Parameters Version 2 X** C4GL code (and interface) by J Leffler. X** RDS interface by M Prowell. X** X** Compilation: X** C4GL: cc -c report.c X** RDS: cc -c -DI4GL_RDS report.c X*/ X X/* X** Addendum to Marlin's comments. X** -- tested on SUNOS 4.1.1 and I4GL-RDS 4.10.UC1 and it seems to work X** correctly, but it is still unsupported code. X*/ X X/* X** From: uunet!nyssa.wa7ipx.ampr.org!mbp (Marlin Prowell) X** Subject: Changing report output params in RDS (code enclosed) X** Date: 29 Apr 92 04:30:46 GMT X** To: informix-list@rmy.emory.edu X** X-Informix-List-Id: X** X** A few days ago, Jonathan Leffler posted some code for I4GL that would X** change report output parameters on the fly. The code he posted works X** only for the C compiler version, and I only have the RDS version of X** Informix. Since an Informix employee said he was unable to figure out X** a RDS version, I took that as a challenge. X** X** Below is a modified version of his report.c that works when linked into X** a customized runner. I leave the details to building the runner as an X** exercise for the reader. X** X** I used Jonathan's code as a hint on how reports work in Informix. I X** found the equivalent report pointer, and inferred the report structure X** that the interpreter uses. Since this code diddles with internal X** interpreter variables, use this code at your own risk. I use it now to X** reset the page length when output is going to the screen, and it X** *appears* to work correctly. Your mileage may vary. X** X** BTW, I am using Informix 4.00 on SCO Xenix. I haven't tested this X** anywhere else. Of course, the size of the junk variable in the repdesc X** structure may change on other machine architectures. You could write X** another C function that gets called in the ON EVERY ROW section, and X** have it print out the values in the repdesc structure. You can then X** verify that the structure definition is correct on your machine. X** X** I've wanted to do this, but after I had previously poked around in the X** interpreter for awhile, I had also given up. Thanks for the hints, Jonathan. X** X** -------------------------------------------------------------------------- X** | Marlin Prowell | There is a very thin line between ignorance | X** | (206) 676-1554 | and arrogance and I have totally obliterated | X** | mbp@nyssa.wa7ipx.ampr.org | that line. -- Dr. Science | X** -------------------------------------------------------------------------- X*/ X X#include X X#ifndef lint Xstatic char sccs[] = "@(#)report.c 2.1 92/07/24"; X#endif X X#ifdef I4GL_RDS X X/* Structure inferred from RDS */ Xtypedef struct repdesc X{ X short junk[42]; /* unknown */ X short ln; /* Line number? */ X short pagenumber; /* Pge number */ X short plength; /* Page length */ X short tmargin; /* Top margin */ X short bmargin; /* Bottom margin */ X short lmargin; /* Left margin */ X short rmargin; /* Right margin */ X short fphlines; /* Lines in first page header */ X short phlines; /* Lines in page header */ X short ptlines; /* Lines in page trailer */ X short junktoo; /* unknown */ X short tot; X} Report; X Xextern Report *currep; /* Parameters of current report */ X X#else X X/* Structure copied from C code generated by I4GL */ Xtypedef struct repdesc X{ X long rrecordnum; /* Record number */ X short pagenumber; /* Pge number */ X short ln; /* Line number? */ X short tmargin; /* Top margin */ X short rmargin; /* Right margin */ X short lmargin; /* Left margin */ X short bmargin; /* Bottom margin */ X short phlines; /* Lines in page header */ X short fphlines; /* Lines in first page header */ X short colcount; X short tot; X short oktoinc; X FILE *outfp; /* Output channel */ X short oftype; X short plength; /* Page length */ X short ptlines; /* Lines in page trailer */ X struct aggdesc *_paggdesc; X struct value *_paggvals; X struct sortdesc *p_sortdesc; X short gotoindx; X short gotostk[5]; X short needlmarg; X} Report; X Xextern Report *c_rp; /* Parameters of current report */ X X#endif /* I4GL_RDS */ X Xstatic Report set; /* Newly set report parameters */ Xstatic int newset = 0; /* Mask of newly set parameters */ X X#define TMARGIN 0x01 X#define BMARGIN 0x02 X#define LMARGIN 0x04 X#define PLENGTH 0x08 X#define RMARGIN 0x10 X X#define DEF_TMARGIN 3 X#define DEF_BMARGIN 3 X#define DEF_LMARGIN 5 X#define DEF_PLENGTH 66 X#define DEF_RMARGIN 132 X X/* Redefine page length */ Xint set_plength(i) Xint i; X{ X if (i == 1) X { X popint(&i); X if (i > 0) X { X set.plength = i; X newset |= PLENGTH; X } X } X return(0); X} X X/* Reset top margin */ X/* This will not reset the top margin on the first page */ Xint set_tmargin(i) Xint i; X{ X if (i == 1) X { X popint(&i); X if (i >= 0) X { X set.tmargin = i; X newset |= TMARGIN; X } X } X return(0); X} X X/* Reset bottom margin */ Xint set_bmargin(i) Xint i; X{ X if (i == 1) X { X popint(&i); X if (i >= 0) X { X set.bmargin = i; X newset |= BMARGIN; X } X } X return(0); X} X X/* Reset left margin */ Xint set_lmargin(i) Xint i; X{ X if (i == 1) X { X popint(&i); X if (i >= 0) X { X set.lmargin = i; X newset |= LMARGIN; X } X } X return(0); X} X X/* Reset right margin */ Xint set_rmargin(i) Xint i; X{ X if (i == 1) X { X popint(&i); X if (i >= 0) X { X set.rmargin = i; X newset |= RMARGIN; X } X } X return(0); X} X X/* Copy reset output list into report configuration */ X/* Call in first page header block */ Xint set_output(i) Xint i; X{ X int newlen; X Report *report; X X#ifdef I4GL_RDS X report = currep; X#else X report = c_rp; X#endif /* I4GL_RDS */ X X if (i == 0 && newset && report != (Report *)0) X { X if (newset & PLENGTH) X { X report->plength = set.plength; X } X if (newset & TMARGIN) X { X newlen = report->plength X - report->ptlines X - report->phlines X - report->bmargin X - report->tmargin X - 1; X if (set.tmargin < newlen) X { X report->tmargin = set.tmargin; X } X } X if (newset & LMARGIN) X { X report->lmargin = set.lmargin; X } X if (newset & BMARGIN) X { X newlen = report->plength X - report->ptlines X - report->phlines X - report->tmargin X - report->bmargin X - 1; X if (set.bmargin < newlen) X { X report->bmargin = set.bmargin; X } X } X /* Adding report->phlines leaves the report */ X /* title at the top of the terminal screen. MP */ X report->tot = report->plength - (report->bmargin + report->ptlines X + report->phlines); X newset = 0; X } X return(0); X} X X/* Return page length */ Xint get_plength(i) Xint i; X{ X if (newset & PLENGTH) X i = set.plength; X else X i = DEF_PLENGTH; X retint(i); X return(1); X} X X/* Return top margin */ Xint get_tmargin(i) Xint i; X{ X if (newset & TMARGIN) X i = set.tmargin; X else X i = DEF_TMARGIN; X retint(i); X return(1); X} X X/* Return bottom margin */ Xint get_bmargin(i) Xint i; X{ X if (newset & BMARGIN) X i = set.bmargin; X else X i = DEF_BMARGIN; X retint(i); X return(1); X} X X/* Return left margin */ Xint get_lmargin(i) Xint i; X{ X if (newset & LMARGIN) X i = set.lmargin; X else X i = DEF_LMARGIN; X retint(i); X return(1); X} X X/* Return right margin */ Xint get_rmargin(i) Xint i; X{ X if (newset & RMARGIN) X i = set.rmargin; X else X i = DEF_RMARGIN; X retint(i); X return(1); X} SHAR-EOF chmod 444 report.c if [ `wc -c rejig.4gl <<'SHAR-EOF' X{ X @(#)rejig.4gl 1.2 89/08/02 15:46:15 X @(#)Sphinx Informix Tools X @(#)Example: Set output parameters of I4GL report dynamically X @(#)J Leffler X @(#)(C) Copyright 1989 Sphinx Ltd. X} X XMAIN X X DEFINE i INTEGER X X START REPORT rf_rejig X X { Adjust report parameters dynamically } X CALL set_tmargin(1) # Top margin X CALL set_bmargin(1) # Bottom margin X CALL set_plength(23) # Page length X CALL set_lmargin(0) # Left margin X X FOR i = 1 TO 30 X OUTPUT TO REPORT rf_rejig(i) X END FOR X X FINISH REPORT rf_rejig X XEND MAIN X XREPORT rf_rejig(i) X X DEFINE i INTEGER X X OUTPUT X { Unusual and distinctive settings } X TOP MARGIN 4 X BOTTOM MARGIN 4 X LEFT MARGIN 15 X PAGE LENGTH 63 X X FORMAT X X FIRST PAGE HEADER X { Reset report parameters } X { Top margin of first page already printed } X CALL set_output() X PRINT "First Page Header" X X PAGE HEADER X PRINT "Other Page Header" X X PAGE TRAILER X PRINT "Page Trailer" X PAUSE "Hit return to continue" X X ON EVERY ROW X PRINT "i = ", i X X ON LAST ROW X SKIP 1 LINE X PRINT "Number of rows = ", COUNT(*) X XEND REPORT {rf_rejig} SHAR-EOF chmod 444 rejig.4gl if [ `wc -c