home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #3 / amigamamagazinepolishissue1998.iso / bazy / scion407 / scionarexx.lha / PrintDescendant.rexx < prev    next >
OS/2 REXX Batch file  |  1995-06-01  |  19KB  |  691 lines

  1. /****************************************************************************
  2.  *                                                                          *
  3.  * $VER: PrintDescendant 2.00 (2 Feb 1995)
  4.  *                                                                          *
  5.  *                      Written by Freddy Ariës                             *
  6.  *                                                                          *
  7.  * Output options:                                                          *
  8.  *  1. Descendant Chart - all descendants [Dutch: parenteel]                *
  9.  *  2. Descendant Chart - male descendants (mention daughters, no children) *
  10.  *     [Dutch: genealogie - nageslacht van zonen, maar vermelding dochters] *
  11.  *  3. Descendant Chart - male descendants (leave out daughters)            *
  12.  *     [Dutch: stamboom - nageslacht van zonen, geen vermelding dochters]   *
  13.  *                                                                          *
  14.  * This version uses (by default) the rexxreqtools.library (which requires  *
  15.  * a version of reqtools larger than 2.0 and rexxsyslib.library)            *
  16.  * If you do not have these, you need to supply the NOREQ argument (for     *
  17.  * Shell output), or the QUIET argument (for no output at all).             *
  18.  *                                                                          *
  19.  * As of v2 of this script, and Scion V4, the current person on Scion's     *
  20.  * Personal Window will be used to determine where the search starts.       *
  21.  * Scion 3.13 can still be used, though, in which case the user will be     *
  22.  * asked at which IRN he wants to start.                                    *
  23.  *                                                                          *
  24.  * TO DO (mostly low priority, unless someone really wants this):           *
  25.  *  - find a good way to handle the people with sex '?'                     *
  26.  *  - count the number of lines output and give a linefeed after a certain  *
  27.  *    number (ie. skip page breaks)                                         *
  28.  *  - add a menu option for the maximum number of generations to print      *
  29.  *  - allow user to specify if he wants burial data printed, occupation,    *
  30.  *    comments, references fields, ....                                     *
  31.  *  - If the person has multiple marriages, output a list to the            *
  32.  *    screen and let the user select one (1..x), or all (0).                *
  33.  *                                                                          *
  34.  ****************************************************************************/
  35.  
  36. options results
  37. arg prtin outname noirn mgen outval
  38.  
  39. versionstr = "2.00"
  40. usereq = 1; /* change this to 0 if you don't want to use reqtools */
  41. outp = 1; useirn = 1; prtdev = stdout; prtopt = 0
  42. plwidth = 78;  /* linewidth of the printer */
  43. NL = '0A'x
  44. PSCR = 'SCIONGEN'; /* public screen to open the requesters on */
  45.  
  46. signal on IOERR
  47.  
  48. do while prtin = '?'
  49.   Tell("NUMOPT/A/N,OUTFILE/A,NOIRN/S,MAXGEN/N,NOREQ/S,QUIET/S: ")
  50.   pull prtin outname noirn mgen outval
  51. end
  52.  
  53. ParseArguments()
  54.  
  55. if usereq & ~show('l','rexxreqtools.library') then do
  56.   if exists('libs:rexxreqtools.library') then
  57.     call addlib('rexxreqtools.library',0,-30,0)
  58.   else do
  59.     usereq = 0; outp = 1
  60.     Tell("Unable to open rexxreqtools.library - using text output")
  61.   end
  62. end
  63.  
  64. /* These few lines were stolen from Peter Billings - thanks Peter ;-) */
  65. if ~show('P','SCIONGEN') then do
  66.   TermError('I am sorry to say that the SCION Genealogist' || NL ||,
  67.     'database is not available. Please start the' || NL ||,
  68.     'SCION program BEFORE using this script!')
  69. end
  70.  
  71. myport = "SCIONGEN"
  72. address value myport
  73. GETDBNAME
  74. dbname = upper(RESULT)
  75. fill = 7;        /* number of spaces at the beginning of lines */
  76. malesex = 'M';   /* as of V4, sexes are always 'M', 'F' or '?' */
  77. femalesex = 'F'
  78. GETPROGVERSION
  79. progvers = RESULT
  80.  
  81. if progvers >= 4 then do
  82.   GETCURRENTIRN
  83.   irn = RESULT
  84. end
  85.  
  86. if outp & ~usereq then do
  87.   Tell("*** PrintDescendant version "||versionstr||" ***")
  88.   Tell("***        by Freddy Ariës       ***")
  89.   Tell("Current database: "||dbname||NL)
  90. end
  91. if prtopt = 0 then do
  92.   if usereq then do
  93.     prtopt = rtezrequest('Current Scion database: '||dbname||NL||,
  94.       NL||'Please make your choice: '||,
  95.       NL||' 1. Descendant Chart - all descendants'||,
  96.       NL||' 2. Descendant Chart - male descendants'||,
  97.       NL||'    (mention daughters, without children)'||,
  98.       NL||' 3. Descendant Chart - male descendants'||,
  99.       NL||'    (leave out daughters)'||,
  100.       '',' _1 | _2 | _3 |E_xit','PrintDescendant v'||versionstr||' by Freddy Ariës','rt_pubscrname = '||PSCR)
  101.     if prtopt = 0 then
  102.       EXIT
  103.  
  104.     if progvers < 4 then do
  105.       irn = rtgetlong(,'Enter the IRN of the person whose'||,
  106.             NL||'descendants you want to print: '||,
  107.             NL,'Input Request:','_Continue','rt_pubscrname = '||PSCR)
  108.       if irn = '' then
  109.         EXIT
  110.       irn = abs(irn)
  111.     end
  112.  
  113.     useirn = rtezrequest('Do you want to output the IRNs'||,
  114.               NL||'(the record numbers) as well?'||,
  115.               '',' _Yes| _No ','Input Request:','rt_pubscrname = '||PSCR)
  116.   end
  117.   else do
  118.     /* No use in asking for input if we're not allowed to output anything */
  119.     Tell("1. Descendant Chart - all descendants")
  120.     Tell("2. Descendant Chart - male descendants (mention daughters, without children)")
  121.     Tell("3. Descendant Chart - male descendants (leave out daughters)")
  122.     TellNN("Your choice: ")
  123.     pull prtopt
  124.     prtopt = CheckAnswer(prtopt)
  125.  
  126.     if progvers < 4 then do
  127.       TellNN("Enter the IRN of the person whose descendants you want to print: ")
  128.       pull irn
  129.     end
  130.  
  131.     TellNN("Do you want to output the IRNs (numbers) as well (y/n)? ")
  132.     pull instr
  133.     Tell("")
  134.     if left(instr, 1) = "Y" then useirn = 1
  135.     else useirn = 0
  136.   end
  137. end
  138.  
  139. if progvers < 4 then do
  140.   irn = CheckIRN(irn)
  141. end
  142.  
  143. EXISTPERSON irn
  144. if RESULT ~= 'YES' then
  145. do
  146.   if progvers >= 4 then
  147.     TermError("Unable to locate current person in the current database.")
  148.   else
  149.     TermError("No person with IRN "||irn||" in the current database.")
  150. end
  151.  
  152. if prtopt > 1 then do
  153.   GETSEX irn
  154.   parsex = RESULT
  155.   if prtopt = 3 & parsex = femalesex then
  156.     TermError("Person isn't male - nothing to print.")
  157. end
  158.  
  159. if outp then do
  160.   /* No use trying to get input if we're not allowed to ask anything */
  161.   pname = GetNameStr(irn, 0)
  162.   if prtopt = 1 | parsex = malesex then do
  163.     if usereq then do
  164.       valcont = rtezrequest('The selected person is: '||NL||pname||'.'||,
  165.         NL||'Continue?','_Continue| _Abort','PrintDescendant Request:','rt_pubscrname = '||PSCR)
  166.       if valcont = 0 then
  167.         EXIT
  168.     end
  169.     else do
  170.       TellNN("Current person is "||pname||". Continue? (y/n) ")
  171.       pull valcont
  172.       if left(valcont, 1) ~= 'Y' then
  173.         TermError("Ok.")
  174.     end
  175.   end
  176.   else do
  177.     /* with prtopt = 2, we would only print the (generation I) female and
  178.      * her husbands, but no children!
  179.      */
  180.     if usereq then do
  181.       valcont = rtezrequest("WARNING!!! Person "||NL||pname||,
  182.         NL||"is not male! Continue anyway?",'_Continue| _Abort','PrintDescendant Request:','rt_pubscrname = '||PSCR)
  183.       if valcont = 0 then
  184.         EXIT
  185.     end
  186.     else do
  187.       Tell("WARNING! Person "||pname||" isn't male!")
  188.       TellNN("Continue anyway? (y/n) ")
  189.       pull valcont
  190.       if left(valcont, 1) ~= 'Y' then
  191.         TermError("Ok.")
  192.     end
  193.   end
  194. end
  195.  
  196. /* TO DO: (at this location:)
  197.  * If the person has multiple marriages, output the spouse name, IRN
  198.  * and FGRN to screen, and let the user select one (1..x), or all (0)
  199.  */
  200.  
  201. if outp & outname = "" then do
  202.   if usereq then do
  203.     odev = rtezrequest('Current Scion database: '||dbname||,
  204.       NL||'Where should the output be sent to?'||,
  205.       NL,' _File |_Printer|_Screen|_Nowhere','PrintDescendant v'||versionstr||' by Freddy Ariës','rt_pubscrname = '||PSCR)
  206.     select
  207.       when odev = 1 then do
  208.         /* We need a file requester for further data */
  209.         dblen = length(dbname)
  210.         if dblen>6 & right(dbname, 6)=".SCION" then
  211.           dbname=left(dbname, dblen - 6)
  212.         outname = rtfilerequest(,dbname||'.DSC','Output filename',,'rtfi_buffer = true   rt_pubscrname = '||PSCR||'   rtfi_initialpath = RAM:',)
  213.         if outname = '' then
  214.           outname = dbname||'.DSC'
  215.       end
  216.       when odev = 2 then
  217.         outname = 'PRT:'
  218.       when odev = 3 then
  219.         outname = 'STDOUT'
  220.       otherwise
  221.         EXIT
  222.         /* You selected 'Nowhere' */
  223.     end
  224.   end
  225.   else do
  226.     Tell("Enter output file (filename with complete path, or PRT: for printer,")
  227.     TellNN("or STDOUT for screen): ")
  228.     pull outname
  229.     if outname = "" then
  230.       outname = "STDOUT"
  231.   end
  232. end
  233.  
  234. /* Anyone know a better way to translate numbers into Roman? */
  235. GenerationS.1 = "I II III IV V VI VII VIII IX X XI XII XIII XIV XV XVI XVII XVIII XIX XX"
  236. GenerationS.2 = "XXI XXII XXIII XXIV XXV XXVI XXVII XXVIII XXIX XXX XXXI XXXII XXXIII XXXIV XXXV XXXVI XXXVII XXXVIII IXL XL"
  237. MaxChild = 26
  238.  
  239. /* Printer Codes, some of which are currently unused: */
  240. ESC = '1B'x
  241. prtinit = ESC||"#1";     /* ESC#1 initialize      */
  242. prtundon = ESC||"[4m";   /* ESC[4m underline on   */
  243. prtundoff = ESC||"[24m"; /* ESC[24m underline off */
  244. prtdson = ESC||"[1m";    /* ESC[1m boldface on    */
  245. prtdsoff = ESC||"[22m";  /* ESC[22m boldface off  */
  246. prtnlqon = ESC||"[2"||'22'x||"z"; /* ESC[2"z NLQ on */
  247. prtnlqoff = ESC||"[1"||'22'x||"z"; /* ESC[1"z NLQ off */
  248.  
  249. if ~usereq then
  250.   Tell("Printing...")
  251.  
  252. OpenPrinter()
  253.  
  254. childnums = irn; childgens = "1"
  255. alcount = 0; chcount = 0
  256.  
  257. do while childnums ~= ""
  258.   irn = word(childnums, 1)
  259.   cgen = word(childgens, 1)
  260.   if cgen ~= currgen then do
  261.     alcount = 0
  262.     /* New generation: reset alfabet counter */
  263.     currgen = cgen
  264.     genchild = 0
  265.   end
  266.   childnums = delstr(childnums, 1, length(irn)+1)
  267.   childgens = delstr(childgens, 1, length(currgen)+1)
  268.  
  269.   ccnt = 1
  270.   /* Sex to use with options 2 and 3 */
  271.   GETSEX irn
  272.   parsex = RESULT
  273.  
  274.   g1 = GetPersonStr(irn)
  275.   mnum = 0
  276.   GETMARRIAGE irn mnum
  277.   fgrn = RESULT
  278.   EXISTFAMILY fgrn
  279.   ftrue = RESULT
  280.  
  281.   do while ftrue = 'YES'
  282.     m1 = GetMarriageStr(fgrn)
  283.     ptn = GetPartnerIRN(fgrn, irn)
  284.     if ptn ~= 0 then do
  285.       if m1 ~= "" then m1 = m1||' '
  286.       m1 = m1||GetPersonStr(ptn)
  287.     end
  288.     if m1 ~= "" then m1 = ", m: "||m1
  289.     if ccnt = 1 then do
  290.       ggs = GetGenStr(currgen, 0)
  291.       if currgen > 1 then do
  292.         alcount = alcount + 1
  293.     /* TO DO: only if this person has any siblings who have children,
  294.      *      or if there are other persons (with children) on this
  295.      *      generation
  296.      */
  297.         ggs = ggs||D2C(alcount+96)
  298.       end
  299.       ggs = left(ggs||".       ", fill)
  300.       m1 = ggs||g1||m1||'.'
  301.       ccnt = 0
  302.     end
  303.     else
  304.       m1 = copies(' ',fill)||g1||m1||'.'
  305.     PrintLines(m1, fill)
  306.     if prtopt ~= 3 | parsex = malesex then
  307.       chcount = chcount + PrintChildren(fgrn, parsex)
  308.     PrintLF()
  309.     mnum = mnum + 1
  310.     GETMARRIAGE irn mnum
  311.     fgrn = RESULT
  312.     EXISTFAMILY fgrn
  313.     ftrue = RESULT
  314.   end
  315.   if mnum = 0 then do
  316.     m1 = GetGenStr(currgen,fill)||g1
  317.     PrintLines(m1, fill)
  318.     if currgen = 1 then
  319.       PrintLines("No marriages are recorded for this person.", 0)
  320.     PrintLF()
  321.   end
  322. end
  323. if currgen = 1 & chcount = 0 then do
  324.   if prtopt = 1 then
  325.     PrintLines("No descendants are recorded for person.")
  326.   else 
  327.     PrintLines("No male descendants are recorded for person.")
  328. end
  329.  
  330. writeln(prtdev, prtnlqoff);
  331. close(prtdev)
  332. if usereq then
  333.   rtezrequest('Output ready.','E_xit','PrintDescendant Message:','rt_pubscrname = '||PSCR)
  334. else
  335.   Tell("Done.")
  336. EXIT
  337.  
  338. ParseArguments:
  339. if noirn = "NOIRN" then useirn = 0
  340. else if noirn = "QUIET" || noirn = "NOREQ" then do
  341.   outval = noirn
  342.   noirn = ""
  343. end
  344. else do
  345.   outval = mgen
  346.   mgen = noirn
  347.   noirn = ""
  348. end
  349. if mgen = "QUIET" || mgen = "NOREQ" then do
  350.   outval = mgen
  351.   mgen = ""
  352. end
  353.  
  354. MaxGens = 40; /* due to the Roman numbers, we can't handle more */
  355. if mgen ~= "" then do
  356.   if DATATYPE(mgen, 'w') & mgen > 0 & mgen < MaxGens then
  357.     MaxGens = mgen
  358. end
  359.  
  360. if outval = "QUIET" then do
  361.   usereq = 0
  362.   outp = 0
  363. end
  364. else if outval = "NOREQ" then
  365.   usereq = 0
  366.  
  367. if prtin = "" then do
  368.   prtopt = 0
  369.   if ~outp then TermError("Requires argument is missing.")
  370.     /* actually, with outp = 0, all it does is EXIT */
  371. end
  372. else do
  373.   prtopt = CheckAnswer(prtin)
  374.   /* Note that it was important to establish outp before calling these */
  375. end  
  376. return 0
  377.  
  378. OpenPrinter:
  379. /* Open the printer device and print out a nice header */
  380. if outname = "STDOUT" then
  381.   prtdev = stdout
  382. else do
  383.   prtdev = 'PRINTER'
  384.   if ~open(prtdev, outname, 'w') then
  385.     TermError("ERROR: Failed to open output file!")
  386. end
  387. writeln(prtdev, prtinit||prtnlqon)
  388. if prtopt = 1 then
  389.   prtstr = "DESCENDANT CHART - ALL DESCENDANTS"
  390. else if prtopt = 2 then
  391.   prtstr = "DESCENDANT CHART - ONLY MALE DESCENDANTS (TYPE I)"
  392. else
  393.   prtstr = "DESCENDANT CHART - ONLY MALE DESCENDANTS (TYPE II)"
  394. prtstr = prtundon||prtdson||prtstr||prtdsoff||prtundoff
  395. writeln(prtdev, prtstr)
  396. prtstr = prtdson||"Report printed on: "||date()||prtdsoff
  397. writeln(prtdev, prtstr)
  398. prtstr = copies('=', plwidth)
  399. writeln(prtdev, prtstr)
  400. return 0
  401.  
  402. PrintLines: PROCEDURE EXPOSE prtdev plwidth prtopt
  403. parse arg ostr, fill
  404. /* TO DO:
  405.  * if there are control strings within ostr (like prtdson or prtdsoff)
  406.  * don't include them in the length count
  407.  */
  408. do while ostr ~= ""
  409.   nnl = plwidth+1
  410.   if length(ostr) > plwidth then do
  411.     do until pc = ' ' | nnl = 1
  412.       pc = substr(ostr, nnl, 1)
  413.       nnl = nnl - 1
  414.     end
  415.     if nnl = 1 then do
  416.       prtstr = left(ostr, plwidth)
  417.       ostr = delstr(ostr, 1, nnl)
  418.     end
  419.     else do
  420.       prtstr = left(ostr, nnl)
  421.       ostr = delstr(ostr, 1, nnl+1)
  422.     end
  423.   end
  424.   else do
  425.     prtstr = ostr
  426.     ostr = ""
  427.   end
  428.   writeln(prtdev, prtstr)
  429.   if ostr ~= "" then
  430.     ostr = copies(' ',fill)||ostr
  431. end
  432. return 0
  433.  
  434. PrintLF:
  435. writeln(prtdev, "")
  436. return 1
  437.  
  438. PrintChildren:
  439. parse arg ffnum, parsx
  440. /* If we turn this into a PROCEDURE, we'll have to EXPOSE a lot!
  441.  * The disadvantage now is that we have to be extremely careful
  442.  * not to overwrite any global variables by accident!
  443.  */
  444. cidx = 0; cham = 0
  445. GETCHILD ffnum cidx
  446. chld = RESULT
  447. EXISTPERSON chld
  448. ctrue = RESULT
  449. nextgen = currgen + 1
  450. if nextgen > MaxGens then return cham
  451.   /* Maximum number of generations reached! */
  452. do while ctrue = 'YES'
  453.   cidx = cidx + 1
  454.   if prtopt > 1 then do
  455.     GETSEX chld
  456.     csx = RESULT
  457.   end
  458.   if prtopt ~= 3 | csx = malesex then do
  459.     cham = cham + 1
  460.     m1 = copies(' ',8)||cham||". "||GetChildStr(chld)
  461.     if (prtopt = 1 | csx = malesex) & HasChild(chld) then do
  462.       childnums = childnums||chld||' '
  463.       childgens = childgens||nextgen||' '
  464.       genchild = genchild + 1
  465.       if genchild > MaxChild then return 1
  466.       /* Maximum number of children reached! */
  467.       /* TO DO: if genchild = 1 and the current person has no siblings,
  468.        *    or none of his siblings have any children of their own,
  469.        *    and if there are no other persons with children on this
  470.        *    generation, then leave off the D2C part
  471.        */
  472.       m1 = m1||", see "||GetGenStr(nextgen, 0)||D2C(genchild+96)
  473.     end
  474.     else
  475.       m1 = m1||GetDeathStr(chld)||GetMarriages(chld)
  476.     PrintLines(m1||'.', 11)
  477.   end
  478.   GETCHILD ffnum cidx
  479.   chld = RESULT
  480.   EXISTPERSON chld
  481.   ctrue = RESULT
  482. end
  483. return cham
  484.  
  485. GetGenStr: PROCEDURE EXPOSE GenerationS.
  486. parse arg gnum, fill
  487. if gnum <= 20 then
  488.   gstr = word(GenerationS.1, gnum)
  489. else if gnum <= 40 then
  490.   gstr = word(GenerationS.2, gnum)
  491. else
  492.   return ""
  493. if fill > 0 then
  494.   gstr = left(gstr||".       ",fill)
  495. return gstr
  496.  
  497. GetPersonStr: PROCEDURE EXPOSE useirn
  498. parse arg irn
  499. if irn ~= 0 then do
  500.   nstr = GetNameStr(irn)
  501.   nstr = nstr||GetBirthStr(irn)
  502.   nstr = nstr||GetDeathStr(irn)
  503. end
  504. else
  505.   nstr = "UNKNOWN"
  506. return nstr
  507.  
  508. GetChildStr: PROCEDURE EXPOSE useirn
  509. parse arg irn
  510. if irn ~= 0 then do
  511.   nstr = GetNameStr(irn)
  512.   nstr = nstr||GetBirthStr(irn)
  513. end
  514. else
  515.   nstr = "UNKNOWN"
  516. return nstr
  517.  
  518. HasChild: PROCEDURE EXPOSE prtopt malesex
  519. parse arg irn
  520. mnum = 0
  521. GETMARRIAGE irn mnum
  522. marr = RESULT
  523. EXISTFAMILY marr
  524. mtrue = RESULT
  525. do while mtrue = 'YES'
  526.   chnxt = 0
  527.   GETCHILD marr chnxt
  528.   ch = RESULT
  529.   EXISTPERSON ch
  530.   ct = RESULT
  531.   if prtopt < 3 then do
  532.     if ct = 'YES' then return 1
  533.   end
  534.   else do
  535.     /* For option 3: search for male children */
  536.     do while ct = 'YES'
  537.       GETSEX ch
  538.       csx = RESULT
  539.       if csx = malesex then return 1
  540.       chnxt = chnxt + 1
  541.       GETCHILD marr chnxt
  542.       ch = RESULT
  543.       EXISTPERSON ch
  544.       ct = RESULT
  545.     end
  546.   end
  547.   mnum = mnum + 1
  548.   GETMARRIAGE irn mnum
  549.   marr = RESULT
  550.   EXISTFAMILY marr
  551.   mtrue = RESULT
  552. end
  553. return 0
  554.  
  555. GetNameStr: PROCEDURE EXPOSE useirn
  556. parse arg gnum
  557. GETFIRSTNAME gnum
  558. name = RESULT
  559. if name ~= "" then name = name||" "
  560. GETLASTNAME gnum
  561. lname = RESULT
  562. if lname = "" then lname = "UNKNOWN"
  563. name = name||lname
  564. if useirn then name = name||" ["gnum"]"
  565. return name
  566.  
  567. GetBirthStr: PROCEDURE
  568. parse arg gnum
  569. GETBIRTHPLACE gnum
  570. bstr = RESULT
  571. GETBIRTHDATE gnum
  572. bdat = RESULT
  573. if bdat ~= "" & bstr ~= "" then bstr = bstr||" "
  574. bstr = bstr||bdat
  575. if bstr ~= "" then bstr = ", b: "||bstr
  576. return bstr
  577.  
  578. GetDeathStr: PROCEDURE
  579. parse arg gnum
  580. GETDEATHPLACE gnum
  581. dstr = RESULT
  582. GETDEATHDATE gnum
  583. ddat = RESULT
  584. if ddat ~= "" & dstr ~= "" then dstr = dstr||" "
  585. dstr = dstr||ddat
  586. if dstr ~= "" then dstr = ", d: "||dstr
  587. return dstr
  588.  
  589. GetMarriages: PROCEDURE EXPOSE useirn
  590. parse arg irn
  591. mstr = ""
  592. GETMARRIAGE irn 0
  593. mf = RESULT
  594. EXISTFAMILY mf
  595. if RESULT = 'YES' then do
  596.   mtrue = 1
  597.   GETMARRIAGE irn 1
  598.   m2 = RESULT
  599.   EXISTFAMILY m2
  600.   if RESULT = 'YES' then mset = 1
  601.   else mset = 0
  602. end
  603. else
  604.   mtrue = 0  
  605. mnum = 0
  606. do while mtrue
  607.   m1 = GetMarriageStr(mf)
  608.   if m1 ~= "" then m1  = m1||' '
  609.   ptn = GetPartnerIRN(mf, irn)
  610.   m1 = m1||GetPersonStr(ptn)
  611.  
  612.   if mset then mstr = ", m("||mnum||"): "||m1
  613.   else mstr = ", m: "||m1
  614.  
  615.   mnum = mnum + 1    
  616.   GETMARRIAGE irn mnum
  617.   mf = RESULT
  618.   EXISTFAMILY mf
  619.   if RESULT ~= 'YES' then mtrue = 0
  620. end
  621. return mstr
  622.  
  623. GetMarriageStr: PROCEDURE
  624. parse arg mf
  625. GETMARRYPLACE mf
  626. mstr = RESULT
  627. GETMARRYDATE mf
  628. mdat = RESULT
  629. if mdat ~= "" & mstr ~= "" then mstr = mstr||" "
  630. mstr = mstr||mdat
  631. return mstr
  632.  
  633. GetPartnerIRN: PROCEDURE
  634. parse arg fnum, inum
  635. GETPRINCIPAL fnum
  636. prn = RESULT
  637. GETSPOUSE fnum
  638. sps = RESULT
  639. if inum = prn then pnum = sps
  640. else if inum = sps then pnum = prn
  641. else pnum = 0
  642. EXISTPERSON pnum
  643. if RESULT ~= 'YES' then pnum = 0
  644. return pnum
  645.  
  646. CheckAnswer: PROCEDURE EXPOSE outp prtdev
  647. parse arg str
  648. str = left(str, 1)
  649. if ~DATATYPE(str, 'w') then
  650.   TermError("Arg(1): not a valid option number.")
  651. if str < 1 | str > 3 then
  652.   TermError("Arg(1): not a valid option number.")
  653. return str
  654.  
  655. CheckIRN: PROCEDURE EXPOSE outp prtdev
  656. parse arg str
  657. if ~DATATYPE(str, 'w') then
  658.   TermError("Arg(2): not a valid IRN.")
  659. return str
  660.  
  661. Tell: PROCEDURE EXPOSE outp
  662. parse arg str
  663. if outp then
  664.   writeln(stdout, str)
  665. return 0
  666.  
  667. TellNN: PROCEDURE EXPOSE outp
  668. parse arg str
  669. if outp then
  670.   writech(stdout, str)
  671. return 0
  672.  
  673. TermError: PROCEDURE EXPOSE outp prtdev usereq PSCR
  674. parse arg str
  675. /* If you turned off stdout, no error messages will be shown! */
  676. if usereq then
  677.   rtezrequest(str,'E_xit','PrintDescendant Message:','rt_pubscrname = '||PSCR)
  678. else do
  679.   Tell(str || '0A'x)
  680. end
  681. close(prtdev)
  682. EXIT
  683.  
  684. /* Let's make sure you get a nice message when you turn off the printer :-) */
  685.  
  686. IOERR:
  687. bline = SIGL
  688. say "I/O error #"||RC||" detected in line "||bline||":"
  689. say sourceline(bline)
  690. EXIT
  691.