home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / database / informix / 1606 < prev    next >
Encoding:
Internet Message Format  |  1992-07-24  |  15.7 KB

  1. Path: sparky!uunet!gatech!pirates!emory!emory.mathcs.emory.edu
  2. From: widener!obelix.informix.com!johnl@emory.mathcs.emory.edu (Jonathan Leffler)
  3. Newsgroups: comp.databases.informix
  4. Subject: INFORMIX-4GL Dynamic Report Output Parameters Version 2
  5. Message-ID: <9227@emory.mathcs.emory.edu>
  6. Date: 24 Jul 92 13:48:05 GMT
  7. Sender: walt@mathcs.emory.edu
  8. Reply-To: widener!obelix.informix.com!johnl@emory.mathcs.emory.edu (Jonathan Leffler)
  9. Lines: 617
  10. X-Informix-List-ID: <list.1340>
  11.  
  12. Some time ago, I lobbed some C code at the net which adapted the output
  13. dimensions of an I4GL report at runtime, with the comment that I hadn't got
  14. it to work with I4GL-RDS.  On 29th April 1992, Marlin Prowell put an
  15. adapted version of my code on to the net, having made it work under
  16. I4GL-RDS.
  17.  
  18. The shell archive below is an integrated version of our two efforts: there
  19. is a compile line parameter -DI4GL_RDS required to make it work under
  20. I4GL-RDS and no parameter for compiled I4GL (I4GL-C?).  There is also an
  21. updated manual page, and some example I4GL code which is used in the manual
  22. page.
  23.  
  24. I hope you find this useful.
  25.  
  26. Marlin: thanks for the effort -- it was a great help.  And for the fix in
  27. the code.  I've kept your comments in the code.
  28.  
  29. Jonathan Leffler (johnl@obelix.informix.com) #include <disclaimer.h>
  30.  
  31. FYI: I didn't cheat and look at the source code for the Informix products.
  32.  
  33. :    "@(#)shar.sh    1.8"
  34. #! /bin/sh
  35. #
  36. #    This is a shell archive.
  37. #    Remove everything above this line and run sh on the resulting file.
  38. #    If this archive is complete, you will see this message at the end:
  39. #    "All files extracted"
  40. #
  41. #    Created: Fri Jul 24 11:43:14 GMT 1992 by johnl at Informix Software Ltd.
  42. #    Files archived in this archive:
  43. #    report.man
  44. #    report.c
  45. #    rejig.4gl
  46. #
  47. #--------------------
  48. if [ -f report.man -a "$1" != "-c" ]
  49. then echo shar: report.man already exists
  50. else
  51. echo 'x - report.man (4043 characters)'
  52. sed -e 's/^X//' >report.man <<'SHAR-EOF'
  53. X'\" @(#)report.man    1.4 92/07/24
  54. X'\" @(#)Manual page: General Library -- Report Configuration
  55. X.ds fC "report.man 1.4 92/07/24
  56. X.TH REPORT 3S "JLSS Informix Tools"
  57. X.SH NAME
  58. Xset_output \(em Dynamically reconfigure dimensions of I4GL report
  59. X.SH SYNOPSIS
  60. X.ft B
  61. Xfunction set_plength(i)
  62. X.br
  63. Xdefine i integer
  64. X.sp
  65. Xfunction set_tmargin(i)
  66. X.br
  67. Xdefine i integer
  68. X.sp
  69. Xfunction set_bmargin(i)
  70. X.br
  71. Xdefine i integer
  72. X.sp
  73. Xfunction set_lmargin(i)
  74. X.br
  75. Xdefine i integer
  76. X.sp
  77. Xfunction set_rmargin(i)
  78. X.br
  79. Xdefine i integer
  80. X.sp
  81. Xfunction set_output()
  82. X.ft R
  83. X.ft B
  84. Xfunction get_plength()
  85. X.sp
  86. Xfunction get_tmargin()
  87. X.sp
  88. Xfunction get_bmargin()
  89. X.sp
  90. Xfunction get_lmargin()
  91. X.sp
  92. Xfunction get_rmargin()
  93. X.ft R
  94. X.SH DESCRIPTION
  95. XThese functions can be used to dynamically reconfigure the layout
  96. Xof the page of an Informix 4GL report.
  97. XThe example program shown below illustrates how they should be used.
  98. X.br
  99. X.ft CW
  100. X.ps 10
  101. X.vs 12
  102. X.nf
  103. X.so rejig.4gl
  104. X.br
  105. X.fi
  106. X.ft
  107. X.ps
  108. X.vs
  109. XThe functions \fIset_plength\fP, \fIset_tmargin\fP,
  110. X\fIset_bmargin\fP, \fIset_lmargin\fP and \fIset_rmargin\fP may be called
  111. Xanywhere inside an I4GL program.
  112. XThe function \fIset_output\fP will have no effect except within a report.
  113. XIt is recommended that \fIset_output\fP be used in the \s-2FIRST
  114. XPAGE HEADER\s0 control block, but it may be used in any control block.
  115. X.P
  116. XAfter the function \fIset_output\fP is called, it invalidates all the settings;
  117. Xto change the settings in a second report, you must call the
  118. Xset-routines again.
  119. XThere is no requirement that all the routines are called (or even any of them).
  120. X.P
  121. XThe functions \fIget_plength\fP, \fIget_tmargin\fP,
  122. X\fIget_bmargin\fP, \fIget_lmargin\fP and \fIget_rmargin\fP may be called
  123. Xanywhere inside an I4GL program.
  124. XIf page dimensions have been set using the set-routines, then the corresponding
  125. Xvalue is returned; otherwise, the corresponding default value is returned.
  126. XAfter \fIset_output\fP has been called, the values returned will be
  127. Xthe default values again; if your report needs to know what its dimensions will
  128. Xbe, it should use the get-routines before calling \fIset_output\fP.
  129. X.SH COMPILATION
  130. XIf compiling for use with compiled Informix-4GL, no special flags are needed.
  131. XIf compiling for use with I4GL-RDS, include -DI4GL_RDS on the command line.
  132. XThe details of building the functions into the \*Cfglgo\*D
  133. Xand \*Cfgldb\*D are given in the corresponding Informix manuals.
  134. XThe necessary definitions for \*cfgiusr.c\*d are:
  135. X.br
  136. X.ft CW
  137. X.ps 10
  138. X.vs 12
  139. X.nf
  140. X#ifdef SET_REPORT
  141. Xextern  int set_output();   /* 0 */
  142. Xextern  int get_rmargin();  /* 0 */
  143. Xextern  int get_tmargin();  /* 0 */
  144. Xextern  int get_bmargin();  /* 0 */
  145. Xextern  int get_lmargin();  /* 0 */
  146. Xextern  int get_plength();  /* 0 */
  147. Xextern  int set_rmargin();  /* 1 */
  148. Xextern  int set_tmargin();  /* 1 */
  149. Xextern  int set_bmargin();  /* 1 */
  150. Xextern  int set_lmargin();  /* 1 */
  151. Xextern  int set_plength();  /* 1 */
  152. X#endif /* SET_REPORT */
  153. X
  154. X#ifdef SET_REPORT
  155. X    { "set_output",     set_output,     0   },
  156. X    { "get_rmargin",    get_rmargin,    0   },
  157. X    { "get_tmargin",    get_tmargin,    0   },
  158. X    { "get_bmargin",    get_bmargin,    0   },
  159. X    { "get_lmargin",    get_lmargin,    0   },
  160. X    { "get_plength",    get_plength,    0   },
  161. X    { "set_rmargin",    set_rmargin,    1   },
  162. X    { "set_tmargin",    set_tmargin,    1   },
  163. X    { "set_bmargin",    set_bmargin,    1   },
  164. X    { "set_lmargin",    set_lmargin,    1   },
  165. X    { "set_plength",    set_plength,    1   },
  166. X#endif /* SET_REPORT */
  167. X.br
  168. X.fi
  169. X.ft
  170. X.ps
  171. X.vs
  172. X.SH WARNINGS
  173. XThis code was designed and tested on an ATT&T 3B2/400 running 
  174. XUNIX System V Release 3.0 using Informix-4GL version 1.10.00C.
  175. XIt has since been tested on a number of other environments (including Versions
  176. X1.10.03, 4.00 and 4.10) on a number of platforms, and has been found to work.
  177. XHowever, the code cannot be guaranteed on any platform or version of I4GL.
  178. XIt is completely unsupported code.
  179. X.SH BUGS
  180. XThe top margin set by \fBset_tmargin\fP does not take effect
  181. Xuntil the second page of output.
  182. X.SH AUTHOR
  183. XJonathan Leffler
  184. X.br
  185. XMarlin Prowell
  186. X.br
  187. XJLSS
  188. X.br
  189. X24th July 1992
  190. SHAR-EOF
  191. chmod 444 report.man
  192. if [ `wc -c <report.man` -ne 4043 ]
  193. then echo shar: report.man unpacked with wrong size
  194. fi
  195. # end of overwriting check
  196. fi
  197. #--------------------
  198. if [ -f report.c -a "$1" != "-c" ]
  199. then echo shar: report.c already exists
  200. else
  201. echo 'x - report.c (7529 characters)'
  202. sed -e 's/^X//' >report.c <<'SHAR-EOF'
  203. X/*
  204. X@(#) File:           report.c
  205. X@(#) Version:        2.1
  206. X@(#) Last changed:   92/07/24
  207. X@(#) Purpose:        I4GL: Reset report output parameters (RDS & C4GL)
  208. X@(#) Author:         J Leffler / M Prowell
  209. X*/
  210. X
  211. X/*TABSTOP=4*/
  212. X
  213. X/*
  214. X** INFORMIX-4GL Dynamic Report Output Parameters Version 2
  215. X** C4GL code (and interface) by J Leffler.
  216. X** RDS interface by M Prowell.
  217. X**
  218. X** Compilation: 
  219. X** C4GL: cc -c report.c
  220. X** RDS:  cc -c -DI4GL_RDS report.c
  221. X*/
  222. X
  223. X/*
  224. X** Addendum to Marlin's comments.
  225. X** -- tested on SUNOS 4.1.1 and I4GL-RDS 4.10.UC1 and it seems to work
  226. X**    correctly, but it is still unsupported code.
  227. X*/
  228. X
  229. X/*
  230. X** From: uunet!nyssa.wa7ipx.ampr.org!mbp (Marlin Prowell)
  231. X** Subject: Changing report output params in RDS (code enclosed)
  232. X** Date: 29 Apr 92 04:30:46 GMT
  233. X** To: informix-list@rmy.emory.edu
  234. X** X-Informix-List-Id: <news.1132>
  235. X** 
  236. X** A few days ago, Jonathan Leffler posted some code for I4GL that would
  237. X** change report output parameters on the fly.  The code he posted works
  238. X** only for the C compiler version, and I only have the RDS version of
  239. X** Informix.  Since an Informix employee said he was unable to figure out
  240. X** a RDS version, I took that as a challenge.
  241. X** 
  242. X** Below is a modified version of his report.c that works when linked into
  243. X** a customized runner.  I leave the details to building the runner as an
  244. X** exercise for the reader.
  245. X** 
  246. X** I used Jonathan's code as a hint on how reports work in Informix.  I
  247. X** found the equivalent report pointer, and inferred the report structure
  248. X** that the interpreter uses.  Since this code diddles with internal
  249. X** interpreter variables, use this code at your own risk.  I use it now to
  250. X** reset the page length when output is going to the screen, and it
  251. X** *appears* to work correctly.  Your mileage may vary.
  252. X** 
  253. X** BTW, I am using Informix 4.00 on SCO Xenix.  I haven't tested this
  254. X** anywhere else.  Of course, the size of the junk variable in the repdesc
  255. X** structure may change on other machine architectures.  You could write
  256. X** another C function that gets called in the ON EVERY ROW section, and
  257. X** have it print out the values in the repdesc structure.  You can then
  258. X** verify that the structure definition is correct on your machine.
  259. X** 
  260. X** I've wanted to do this, but after I had previously poked around in the
  261. X** interpreter for awhile, I had also given up.  Thanks for the hints, Jonathan.
  262. X** 
  263. X**  -------------------------------------------------------------------------- 
  264. X** | Marlin Prowell            | There is a very thin line between ignorance  |
  265. X** | (206) 676-1554            | and arrogance and I have totally obliterated |
  266. X** | mbp@nyssa.wa7ipx.ampr.org | that line.             -- Dr. Science        |
  267. X**  -------------------------------------------------------------------------- 
  268. X*/
  269. X
  270. X#include <stdio.h>
  271. X
  272. X#ifndef lint
  273. Xstatic  char    sccs[] = "@(#)report.c    2.1 92/07/24";
  274. X#endif
  275. X
  276. X#ifdef I4GL_RDS
  277. X
  278. X/* Structure inferred from RDS */
  279. Xtypedef struct repdesc
  280. X{
  281. X    short junk[42];     /* unknown       */
  282. X    short ln;           /* Line number?  */
  283. X    short pagenumber;   /* Pge number    */
  284. X    short plength;      /* Page length */
  285. X    short tmargin;      /* Top margin    */
  286. X    short bmargin;      /* Bottom margin */
  287. X    short lmargin;      /* Left margin   */
  288. X    short rmargin;      /* Right margin  */
  289. X    short fphlines;     /* Lines in first page header */
  290. X    short phlines;      /* Lines in page header */
  291. X    short ptlines;      /* Lines in page trailer */
  292. X    short junktoo;      /* unknown       */
  293. X    short tot;
  294. X}  Report;
  295. X
  296. Xextern  Report *currep;   /* Parameters of current report */
  297. X
  298. X#else
  299. X
  300. X/* Structure copied from C code generated by I4GL */
  301. Xtypedef struct repdesc
  302. X{
  303. X    long rrecordnum;    /* Record number */
  304. X    short pagenumber;   /* Pge number    */
  305. X    short ln;           /* Line number?  */
  306. X    short tmargin;      /* Top margin    */
  307. X    short rmargin;      /* Right margin  */
  308. X    short lmargin;      /* Left margin   */
  309. X    short bmargin;      /* Bottom margin */
  310. X    short phlines;      /* Lines in page header */
  311. X    short fphlines;     /* Lines in first page header */
  312. X    short colcount;
  313. X    short tot;
  314. X    short oktoinc;
  315. X    FILE *outfp;        /* Output channel */
  316. X    short oftype;
  317. X    short plength;      /* Page length */
  318. X    short ptlines;      /* Lines in page trailer */
  319. X    struct aggdesc *_paggdesc;
  320. X    struct value *_paggvals;
  321. X    struct sortdesc *p_sortdesc;
  322. X    short gotoindx;
  323. X    short gotostk[5];
  324. X    short needlmarg;
  325. X}  Report;
  326. X
  327. Xextern  Report *c_rp;   /* Parameters of current report */
  328. X
  329. X#endif    /* I4GL_RDS */
  330. X
  331. Xstatic  Report set;     /* Newly set report parameters  */
  332. Xstatic  int newset = 0; /* Mask of newly set parameters */
  333. X
  334. X#define TMARGIN 0x01
  335. X#define BMARGIN 0x02
  336. X#define LMARGIN 0x04
  337. X#define PLENGTH 0x08
  338. X#define RMARGIN 0x10
  339. X
  340. X#define DEF_TMARGIN   3
  341. X#define DEF_BMARGIN   3
  342. X#define DEF_LMARGIN   5
  343. X#define DEF_PLENGTH  66
  344. X#define DEF_RMARGIN 132
  345. X
  346. X/* Redefine page length */
  347. Xint set_plength(i)
  348. Xint i;
  349. X{
  350. X    if (i == 1)
  351. X    {
  352. X        popint(&i);
  353. X        if (i > 0)
  354. X        {
  355. X            set.plength = i;
  356. X            newset |= PLENGTH;
  357. X        }
  358. X    }
  359. X    return(0);
  360. X}
  361. X
  362. X/* Reset top margin */
  363. X/* This will not reset the top margin on the first page */
  364. Xint set_tmargin(i)
  365. Xint i;
  366. X{
  367. X    if (i == 1)
  368. X    {
  369. X        popint(&i);
  370. X        if (i >= 0)
  371. X        {
  372. X            set.tmargin = i;
  373. X            newset |= TMARGIN;
  374. X        }
  375. X    }
  376. X    return(0);
  377. X}
  378. X
  379. X/* Reset bottom margin */
  380. Xint set_bmargin(i)
  381. Xint i;
  382. X{
  383. X    if (i == 1)
  384. X    {
  385. X        popint(&i);
  386. X        if (i >= 0)
  387. X        {
  388. X            set.bmargin = i;
  389. X            newset |= BMARGIN;
  390. X        }
  391. X    }
  392. X    return(0);
  393. X}
  394. X
  395. X/* Reset left margin */
  396. Xint set_lmargin(i)
  397. Xint i;
  398. X{
  399. X    if (i == 1)
  400. X    {
  401. X        popint(&i);
  402. X        if (i >= 0)
  403. X        {
  404. X            set.lmargin = i;
  405. X            newset |= LMARGIN;
  406. X        }
  407. X    }
  408. X    return(0);
  409. X}
  410. X
  411. X/* Reset right margin */
  412. Xint set_rmargin(i)
  413. Xint i;
  414. X{
  415. X    if (i == 1)
  416. X    {
  417. X        popint(&i);
  418. X        if (i >= 0)
  419. X        {
  420. X            set.rmargin = i;
  421. X            newset |= RMARGIN;
  422. X        }
  423. X    }
  424. X    return(0);
  425. X}
  426. X
  427. X/* Copy reset output list into report configuration */
  428. X/* Call in first page header block */
  429. Xint set_output(i)
  430. Xint i;
  431. X{
  432. X    int newlen;
  433. X    Report    *report;
  434. X
  435. X#ifdef I4GL_RDS
  436. X    report = currep;
  437. X#else
  438. X    report = c_rp;
  439. X#endif    /* I4GL_RDS */
  440. X
  441. X    if (i == 0 && newset && report != (Report *)0)
  442. X    {
  443. X        if (newset & PLENGTH)
  444. X        {
  445. X            report->plength = set.plength;
  446. X        }
  447. X        if (newset & TMARGIN)
  448. X        {
  449. X            newlen  = report->plength
  450. X                    - report->ptlines
  451. X                    - report->phlines
  452. X                    - report->bmargin
  453. X                    - report->tmargin
  454. X                    - 1;
  455. X            if (set.tmargin < newlen)
  456. X            {
  457. X                report->tmargin = set.tmargin;
  458. X            }
  459. X        }
  460. X        if (newset & LMARGIN)
  461. X        {
  462. X            report->lmargin = set.lmargin;
  463. X        }
  464. X        if (newset & BMARGIN)
  465. X        {
  466. X            newlen  = report->plength
  467. X                    - report->ptlines
  468. X                    - report->phlines
  469. X                    - report->tmargin
  470. X                    - report->bmargin
  471. X                    - 1;
  472. X            if (set.bmargin < newlen)
  473. X            {
  474. X                report->bmargin = set.bmargin;
  475. X            }
  476. X        }
  477. X        /* Adding report->phlines leaves the report     */
  478. X        /* title at the top of the terminal screen.  MP */
  479. X        report->tot = report->plength - (report->bmargin + report->ptlines
  480. X                        + report->phlines);
  481. X        newset = 0;
  482. X    }
  483. X    return(0);
  484. X}
  485. X
  486. X/* Return page length */
  487. Xint get_plength(i)
  488. Xint i;
  489. X{
  490. X    if (newset & PLENGTH)
  491. X        i = set.plength;
  492. X    else
  493. X        i = DEF_PLENGTH;
  494. X    retint(i);
  495. X    return(1);
  496. X}
  497. X
  498. X/* Return top margin */
  499. Xint get_tmargin(i)
  500. Xint i;
  501. X{
  502. X    if (newset & TMARGIN)
  503. X        i = set.tmargin;
  504. X    else
  505. X        i = DEF_TMARGIN;
  506. X    retint(i);
  507. X    return(1);
  508. X}
  509. X
  510. X/* Return bottom margin */
  511. Xint get_bmargin(i)
  512. Xint i;
  513. X{
  514. X    if (newset & BMARGIN)
  515. X        i = set.bmargin;
  516. X    else
  517. X        i = DEF_BMARGIN;
  518. X    retint(i);
  519. X    return(1);
  520. X}
  521. X
  522. X/* Return left margin */
  523. Xint get_lmargin(i)
  524. Xint i;
  525. X{
  526. X    if (newset & LMARGIN)
  527. X        i = set.lmargin;
  528. X    else
  529. X        i = DEF_LMARGIN;
  530. X    retint(i);
  531. X    return(1);
  532. X}
  533. X
  534. X/* Return right margin */
  535. Xint get_rmargin(i)
  536. Xint i;
  537. X{
  538. X    if (newset & RMARGIN)
  539. X        i = set.rmargin;
  540. X    else
  541. X        i = DEF_RMARGIN;
  542. X    retint(i);
  543. X    return(1);
  544. X}
  545. SHAR-EOF
  546. chmod 444 report.c
  547. if [ `wc -c <report.c` -ne 7529 ]
  548. then echo shar: report.c unpacked with wrong size
  549. fi
  550. # end of overwriting check
  551. fi
  552. #--------------------
  553. if [ -f rejig.4gl -a "$1" != "-c" ]
  554. then echo shar: rejig.4gl already exists
  555. else
  556. echo 'x - rejig.4gl (1226 characters)'
  557. sed -e 's/^X//' >rejig.4gl <<'SHAR-EOF'
  558. X{
  559. X    @(#)rejig.4gl 1.2 89/08/02 15:46:15
  560. X    @(#)Sphinx Informix Tools
  561. X    @(#)Example: Set output parameters of I4GL report dynamically
  562. X    @(#)J Leffler
  563. X    @(#)(C) Copyright 1989 Sphinx Ltd.
  564. X}
  565. X
  566. XMAIN
  567. X
  568. X    DEFINE i INTEGER
  569. X
  570. X    START REPORT rf_rejig
  571. X
  572. X    { Adjust report parameters dynamically }
  573. X    CALL set_tmargin(1)     # Top margin
  574. X    CALL set_bmargin(1)     # Bottom margin
  575. X    CALL set_plength(23)    # Page length
  576. X    CALL set_lmargin(0)     # Left margin
  577. X
  578. X    FOR i = 1 TO 30
  579. X        OUTPUT TO REPORT rf_rejig(i)
  580. X    END FOR
  581. X
  582. X    FINISH REPORT rf_rejig
  583. X
  584. XEND MAIN
  585. X
  586. XREPORT rf_rejig(i)
  587. X
  588. X    DEFINE i INTEGER
  589. X
  590. X    OUTPUT
  591. X        { Unusual and distinctive settings }
  592. X        TOP MARGIN 4
  593. X        BOTTOM MARGIN 4
  594. X        LEFT MARGIN 15
  595. X        PAGE LENGTH 63
  596. X
  597. X    FORMAT
  598. X
  599. X    FIRST PAGE HEADER
  600. X        { Reset report parameters }
  601. X        { Top margin of first page already printed }
  602. X        CALL set_output()
  603. X        PRINT "First Page Header"
  604. X
  605. X    PAGE HEADER
  606. X        PRINT "Other Page Header"
  607. X
  608. X    PAGE TRAILER
  609. X        PRINT "Page Trailer"
  610. X        PAUSE "Hit return to continue"
  611. X
  612. X    ON EVERY ROW
  613. X        PRINT "i = ", i
  614. X
  615. X    ON LAST ROW
  616. X        SKIP 1 LINE
  617. X        PRINT "Number of rows = ", COUNT(*)
  618. X
  619. XEND REPORT {rf_rejig}
  620. SHAR-EOF
  621. chmod 444 rejig.4gl
  622. if [ `wc -c <rejig.4gl` -ne 1226 ]
  623. then echo shar: rejig.4gl unpacked with wrong size
  624. fi
  625. # end of overwriting check
  626. fi
  627. echo All files extracted
  628. exit 0
  629.