home *** CD-ROM | disk | FTP | other *** search
/ Aminet 10 / aminetcdnumber101996.iso / Aminet / util / rexx / ScionRexx.lha / Links.rexx < prev    next >
OS/2 REXX Batch file  |  1995-11-01  |  12KB  |  422 lines

  1. /****************************************************************************
  2.  *                                                                          *
  3.  * $VER: Links 1.18 (31 Oct 1995)
  4.  *                                                                          *
  5.  *                      Written by Freddy Ariës                             *
  6.  * Address: Lindeboomweg 7, NL-7135 KE Harreveld, The Netherlands.          *
  7.  *                                                                          *
  8.  * ARexx script to find unrelated family trees in the database              *
  9.  * It will detect all family trees within the database that have no links   *
  10.  * (spouse, parent or child links) to other present family trees.           *
  11.  * Eg. useful to find out if you forgot to add a link somewhere...          *
  12.  *                                                                          *
  13.  * This script uses (by default) the rexxreqtools.library (which requires   *
  14.  * a version of reqtools larger than 2.0 and rexxsyslib.library)            *
  15.  * If you do not have these, run SetDefaults.rexx to change the settings.   *
  16.  *                                                                          *
  17.  * DONE:                                                                    *
  18.  * - progress indicator, using rexxarplib.library (requested by R.Akins)    *
  19.  * - now uses preference file for default settings                          *
  20.  *                                                                          *
  21.  ****************************************************************************/
  22.  
  23. options results
  24. arg outname outval
  25.  
  26. versionstr = "1.18"
  27.  
  28. /* Don't change the settings here! Run SetDefaults.rexx instead! */
  29. usereq = 1; prgrs = 1; pgopen = 0
  30. outp = 1; output = stdout; scrdev = stdout
  31. PSCR = 'SCIONGEN'
  32. plwidth = 78; pgsize = 0
  33.  
  34. fill = 4;      /* number of spaces at the beginning of lines */
  35. useirn = 1; pgline = 1
  36. scrname = "CON:0//639//Scion Output/AUTO/SCREEN"
  37. NL = '0A'x
  38.  
  39. signal on IOERR
  40.  
  41. do while outname = '?'
  42.   writeln(stdout, "OUTFILE/A,QUIET/S,NOREQ/S ")
  43.   pull outname outval
  44. end
  45.  
  46. /* read preferences file */
  47.  
  48. if open(pfile, 'ENV:Scion/ScionRexx.prefs', 'r') then do
  49.   do while ~eof(pfile)
  50.     inln = readln(pfile)
  51.     if inln ~= "" then do
  52.       wstr = upper(word(inln, 1))
  53.       if wstr = "USEREQ" then
  54.         usereq = 1
  55.       else if wstr = "NOUSEREQ" then
  56.         usereq = 0
  57.       else if wstr = "PROGRESS" then
  58.         prgrs = 1
  59.       else if wstr = "NOPROGRESS" then
  60.         prgrs = 0
  61.       else if wstr = "PUBSCREEN" then
  62.         pscr = strip(delstr(inln, 1, length(wstr)), 'b', ' "')
  63.       else if wstr = "LINEWIDTH" then do
  64.         wstr = word(inln, 2)
  65.         if datatype(wstr, 'w') then plwidth = wstr
  66.       end
  67.       else if wstr = "PAGESIZE" then do
  68.         wstr = word(inln, 2)
  69.         if datatype(wstr, 'w') then pgsize = wstr
  70.       end
  71.     end
  72.   end
  73.   close(pfile)
  74. end
  75.  
  76. if pscr = "" | (pscr ~= "WORKBENCH" & ~show('p', pscr)) then
  77.   pscr = "SCIONGEN"
  78. scrname = scrname||pscr
  79.  
  80. /* command line options get priority over global settings */
  81.  
  82. if outname ~= "" then do
  83.   if outname = "QUIET" | outname = "NOREQ" then do
  84.     outval = outname; outname = ""
  85.   end
  86. end
  87.  
  88. if outval = "QUIET" then do
  89.   outp = 0; usereq = 0; prgrs = 0
  90. end
  91. else if outval = "NOREQ" then do
  92.   usereq = 0; prgrs = 0
  93. end
  94.  
  95. if usereq & ~show('l','rexxreqtools.library') then do
  96.   if exists('libs:rexxreqtools.library') then
  97.     call addlib('rexxreqtools.library',0,-30,0)
  98.   else do
  99.     usereq = 0; outp = 1
  100.     Tell("Unable to open rexxreqtools.library - using text output")
  101.   end
  102. end
  103.  
  104. if ~usereq then prgrs = 0
  105.  
  106. /* Originally stolen from Peter Billing - thanks Peter ;-) */
  107. if ~show('P','SCIONGEN') then do
  108.   EndString('I am sorry to say that the SCION Genealogist' || NL ||,
  109.     'database is not available. Please start the' || NL ||,
  110.     'SCION program BEFORE using this script!')
  111. end
  112.  
  113. if prgrs & ~show('l','rexxarplib.library') then do
  114.   if exists('libs:rexxarplib.library') then
  115.     call addlib('rexxarplib.library',0,-30,0)
  116.   else
  117.     prgrs = 0
  118. end
  119.  
  120. screentofront(pscr)
  121.  
  122. myport = "SCIONGEN"
  123. address value myport
  124. GETDBNAME
  125. dbname = upper(RESULT)
  126.  
  127. Arrays. = ""
  128. CurrIRN = 1; arr = 1; Arrays.1 = "1 "
  129. NumArrs = 1; Found = 1
  130.  
  131. if outp & ~usereq then do
  132.   if pscr ~= "WORKBENCH" then do
  133.     scrdev = 'SCNLNKSCR'
  134.     if ~open(scrdev, scrname, 'w') then scrdev = stdout
  135.   end
  136.   Tell("Scion Links Finder v"||versionstr||" by Freddy Ariës")
  137.   Tell("Current Scion database: "||dbname)
  138.   Tell("Be patient - this may take a while...")
  139. end
  140.  
  141. /* It's a good habit to add the ".scion" extension to Scion database files */
  142. dblen = length(dbname)
  143. if dblen>6 & right(dbname, 6)=".SCION" then dbname=left(dbname, dblen - 6)
  144.  
  145. if outname = "" then do
  146.   if outp then do
  147.     if usereq then do
  148.       odev = rtezrequest('Current Scion database: '||dbname||,
  149.        NL||'Where should the Links output be sent to?'||,
  150.        NL,' _File |_Printer|_Screen|_Nowhere','Scion Links Finder v'||versionstr||' by Freddy Ariës','rt_pubscrname = '||PSCR)
  151.       select
  152.         when odev = 1 then do
  153.           /* We need a file requester for further data */
  154.           outname = rtfilerequest(,dbname||'.LNK','Output filename',,'rtfi_buffer = true   rt_pubscrname = '||PSCR||'   rtfi_initialpath = RAM:',)
  155.           if outname = '' then
  156.             outname = dbname||'.LNK'
  157.         end
  158.         when odev = 2 then
  159.           outname = 'PRT:'
  160.         when odev = 3 then
  161.           outname = 'STDOUT'
  162.         otherwise
  163.           EXIT
  164.           /* You selected 'Nowhere' */
  165.       end
  166.     end
  167.     else do
  168.       Tell("Enter output file (filename with complete path, or PRT: for printer,")
  169.       TellNN("or STDOUT for screen): ")
  170.       outname = readln(scrdev)
  171.       outname = strip(outname, 'b', ' "')
  172.       Tell("Destination: "||outname)
  173.       TellNN("Continue (y/n)? ")
  174.       conf = readln(scrdev)
  175.       conf = upper(left(conf, 1))
  176.       /* Note that left works on empty strings ("") too! */
  177.       if conf ~= "Y" then
  178.         EndString("Goodbye...")
  179.       Tell("")
  180.     end
  181.   end
  182.   else
  183.     outname = "RAM:"dbname".LNK"
  184.     /* If we're not allowed to use stdout, default to this filename */
  185. end
  186.  
  187. if prgrs then do
  188.   Postmsg(10, 10, "Scion Links Finder (by Freddy Ariës)\Database: "||dbname||"\ \ ", PSCR)
  189.   pgopen = 1
  190. end
  191.  
  192. GETTOTALIRN
  193. TotalIRN = RESULT
  194. if pgopen then Postmsg(,, "\\Processing person:\", PSCR)
  195.  
  196. do while CurrIRN <= TotalIRN
  197.   if pgopen then Postmsg(,,"\\\"||CurrIRN||" (of "||TotalIRN||")", PSCR)
  198.   if Found then do
  199.     MarrNum = 0; marrexist = 1
  200.  
  201.     do while marrexist
  202.       GETMARRIAGE CurrIRN MarrNum
  203.       marriage = RESULT
  204.       EXISTFAMILY marriage
  205.       if RESULT = 'YES' then do
  206.         marrexist = 1
  207.  
  208.     PrsnIRN = 0
  209.     GETPRINCIPAL marriage
  210.     ptnr = RESULT
  211.     EXISTPERSON ptnr
  212.     if RESULT = 'YES' then do
  213.       if ptnr ~= CurrIRN then PrsnIRN = ptnr
  214.     end
  215.     if PrsnIRN = 0 then do
  216.       GETSPOUSE marriage
  217.       ptnr = RESULT
  218.       EXISTPERSON ptnr
  219.       if RESULT = 'YES' then do
  220.         if ptnr ~= CurrIRN then PrsnIRN = ptnr
  221.       end
  222.     end
  223.  
  224.     EXISTPERSON PrsnIRN
  225.         if RESULT = 'YES' then
  226.           arr = HandlePerson(PrsnIRN)
  227.  
  228.     ChildNum = 0; childexist = 1
  229.     do while childexist
  230.       GETCHILD marriage ChildNum
  231.       child = RESULT
  232.       EXISTPERSON child
  233.       if RESULT = 'YES' then do
  234.             childexist = 1
  235.         arr = HandlePerson(child)
  236.         ChildNum = ChildNum + 1
  237.       end
  238.       else childexist = 0
  239.     end
  240.  
  241.         MarrNum = MarrNum + 1
  242.       end
  243.       else marrexist = 0
  244.     end
  245.  
  246.     GETPARENTS CurrIRN
  247.     ParFGRN = RESULT
  248.     EXISTFAMILY ParFGRN
  249.     if RESULT = 'YES' then do
  250.       GETPRINCIPAL ParFGRN
  251.       PrsnIRN = RESULT
  252.       EXISTPERSON PrsnIRN
  253.       if RESULT = 'YES' then do
  254.         arr = HandlePerson(PrsnIRN)
  255.       end
  256.  
  257.       GETSPOUSE ParFGRN
  258.       PrsnIRN = RESULT
  259.       EXISTPERSON PrsnIRN
  260.       if RESULT = 'YES' then
  261.         arr = HandlePerson(PrsnIRN)
  262.  
  263.       /* Note that we don't have to process siblings, because they will
  264.        * be processed with their parents, and because you cannot create
  265.        * a family group without at least one parent
  266.        */
  267.     end
  268.   end
  269.  
  270.   CurrIRN = CurrIRN + 1
  271.   EXISTPERSON CurrIRN
  272.  
  273.   if RESULT = 'YES' then do
  274.    arr = GetArray(CurrIRN)
  275.    Found = 1
  276.   end
  277.   else Found = 0
  278. end
  279.  
  280. if pgopen then Postmsg(,, "\\Writing output...\ ", PSCR)
  281.  
  282. if outname ~= "STDOUT" then do
  283.   output = 'OUTPUT'
  284.   if ~open(output, outname, "w") then
  285.     EndString("ERROR: Unable to open output file.")
  286. end
  287. else
  288.   output = scrdev
  289.  
  290. /* Now output the resulting arrays of IRNs! */
  291. do out = 1 for NumArrs
  292.   PrintLines("Group "||out||": "||Arrays.out, fill)
  293. end
  294.  
  295. if usereq then do
  296.   rtezrequest('Scion Links Finder is ready.' || NL ||'Persons parsed: '||,
  297.     TotalIRN,'_Ok','Links Message:','rt_pubscrname = '||PSCR)
  298.   if pgopen then Postmsg()
  299. end
  300. else
  301.   EndString("Done ("||TotalIRN||" persons parsed)."||NL)
  302.  
  303. EXIT
  304.  
  305. GetArray: PROCEDURE EXPOSE Arrays. NumArrs
  306. parse arg prsn
  307. do CurrArr = 1 for NumArrs
  308.   col = find(Arrays.CurrArr, prsn)
  309.   if col > 0 then return CurrArr
  310. end
  311. /* Not already present, then give person a new array */
  312. NumArrs = NumArrs + 1
  313. Arrays.NumArrs = prsn||' '
  314. return NumArrs
  315.  
  316. MergeArrs: PROCEDURE EXPOSE Arrays. NumArrs
  317. parse arg arr1, arr2
  318. if arr1 <= arr2 then do
  319.   minarr = arr1; maxarr = arr2
  320. end
  321. else do
  322.   minarr = arr2; maxarr = arr1
  323. end
  324. Arrays.minarr = Arrays.minarr||Arrays.maxarr
  325. if maxarr ~= NumArrs then
  326.   Arrays.maxarr = Arrays.NumArrs
  327. Arrays.NumArrs = ""
  328. NumArrs = NumArrs - 1
  329. return minarr
  330.  
  331. HandlePerson: PROCEDURE EXPOSE Arrays. NumArrs arr
  332. parse arg prsn
  333. CurrArr = 1; pers = 0
  334. do until pers ~=  0 | CurrArr > NumArrs
  335.   if find(Arrays.CurrArr, prsn) > 0 then pers = CurrArr
  336.   CurrArr = CurrArr + 1
  337. end
  338. if pers = 0 then do
  339.   /* Person isn't already present; give him same array as CurrIRN person */
  340.   pers = arr
  341.   Arrays.arr = Arrays.arr||prsn||' '
  342. end
  343. if pers ~= arr then
  344.   arr = MergeArrs(pers, arr)
  345. return arr
  346.  
  347. PrintLines: PROCEDURE EXPOSE output plwidth pgline pgsize
  348. parse arg ostr, fill
  349. do while ostr ~= ""
  350.   nnl = plwidth
  351.   if length(ostr) >= plwidth then do
  352.     do until pc = ' ' | nnl = 1
  353.       pc = substr(ostr, nnl, 1)
  354.       nnl = nnl - 1
  355.     end
  356.     if nnl = 1 then do
  357.       prtstr = left(ostr, plwidth-1)
  358.       ostr = delstr(ostr, 1, nnl)
  359.     end
  360.     else do
  361.       prtstr = left(ostr, nnl)
  362.       ostr = delstr(ostr, 1, nnl+1)
  363.     end
  364.   end
  365.   else do
  366.     prtstr = ostr
  367.     ostr = ""
  368.   end
  369.   DoWrite(output, prtstr)
  370.   if ostr ~= "" then
  371.     ostr = copies(' ',fill)||ostr
  372. end
  373. return 0
  374.  
  375. /*
  376.  * output at most #pgsize lines per page to the print device
  377.  * if pgsize = 0, this feature is turned off (unlimited #lines per page)
  378.  */
  379. DoWrite: PROCEDURE EXPOSE pgline pgsize
  380. parse arg prtdev, ostr
  381. if pgsize ~= 0 & pgline > pgsize then do
  382.   writech(prtdev, '0C'x); /* CTRL-L; next page */
  383.   pgline = 0
  384. end
  385. writeln(prtdev, ostr)
  386. pgline = pgline + 1
  387. return 0
  388.  
  389. Tell: PROCEDURE EXPOSE outp scrdev
  390. parse arg str
  391. if outp then writeln(scrdev, str)
  392. return 0
  393.  
  394. TellNN: PROCEDURE EXPOSE outp scrdev
  395. parse arg str
  396. if outp then writech(scrdev, str)
  397. return 0
  398.  
  399. EndString: PROCEDURE EXPOSE outp output usereq pgopen scrdev pscr
  400. parse arg str
  401. if pgopen then Postmsg()
  402. /* If you turned off stdout, no error messages will be shown! */
  403. if usereq then
  404.   rtezrequest(str,'E_xit','Links Message:','rt_pubscrname = '||PSCR)
  405. else do
  406.   Tell(str || '0A'x)
  407. end
  408. if outp & ~usereq & (scrdev ~= stdout) then do
  409.   Tell("Press <return> to exit.")
  410.   readln(scrdev)
  411.   close(scrdev)
  412. end
  413. close(output)
  414. EXIT
  415.  
  416. IOERR:
  417.   bline = SIGL
  418.   say "I/O error #"||RC||" detected in line "||bline||":"
  419.   say sourceline(bline)
  420.   if pgopen then Postmsg()
  421.   EXIT
  422.