home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
new
/
biz
/
dbase
/
genealogist
/
arexx
/
gedcom2scion.rexx
< prev
next >
Wrap
OS/2 REXX Batch file
|
1994-05-21
|
21KB
|
730 lines
/****************************************************************************
* *
* *
* $VER: GEDCOM2Scion.rexx 1.08 (1 Mar 1994)
* *
* Written by Freddy Ariës *
* *
* This program was created to import GEDCOM data into the Scion database. *
* It is still very basic and not user-friendly at all. *
* I assume it will only be able to parse the most basic GEDCOM files, and *
* I can't even guarantee that it will handle these correctly... *
* *
* Even though this script does no parsing of dates, it's safer if they are *
* in the exact format "DD MMM YYYY". *
* All unrecognized fields or fields that Scion doesn't use, are skipped. *
* The database must be running for this AREXX script to work. *
* NOTE: The program generates a file DATABASE.err (where DATABASE is the *
* name of the current Scion database), containing parsing info about *
* which lines were skipped and which non-fatal errors were encountered. *
* It may be a good idea to read this file! *
* *
* TO DO: *
* - Better solution for the user-defined PERSONAL and FAMILY fields *
* (PERSUSER1, PERSUSER2, PERSUSER3, FAMUSER1, FAMUSER2) *
* Current solution: assume defaults *
* - Better parsing of dates *
* Recognition and use of ABT, BEF, AFT notations *
* *
****************************************************************************/
options failat 20; options results
arg inname inval
versionstr = "1.08"
outp = 1; usereq = 1; output = stdout
NL = '0A'x
signal on IOERR
/* parse command line options, to enable calling the script automatically,
* eg. from a function key
*/
do while inname = '?'
writeln(stdout, "INFILE/A,QUIET/S,NOREQ/S ")
pull inname inval
end
if inname ~= "" then do
if inname = "QUIET" | inname = "NOREQ" then do
inval = inname; inname = ""
end
end
if inval = "QUIET" then do
outp = 0; usereq = 0
end
else if inval = "NOREQ" then usereq = 0
if usereq & ~show('l','rexxreqtools.library') then do
if exists('libs:rexxreqtools.library') then
call addlib('rexxreqtools.library',0,-30,0)
else do
usereq = 0; outp = 1
Tell("Unable to open rexxreqtools.library - using text output")
end
end
/* These first few lines are stolen from Peter Billings - thanks Peter ;-) */
if ~show('P','SCIONGEN') then do
TermError('I am sorry to say that the SCION Genealogist' || NL ||,
'database is not available. Please start the' || NL ||,
'SCION program BEFORE using this script!')
end
myport = "SCIONGEN"
address value myport
GETDBNAME
dbname = upper(RESULT)
if outp & ~usereq then do
Tell("GEDCOM to Scion conversion script v"||versionstr||" by Freddy Ariës")
Tell("Scion (output) database: "||dbname)
end
if inname = "" then do
/* ignore the value of outp; if we can't ask for the input file,
* we can't do anything!
*/
if usereq then do
/* We need a file requester for further data */
inname = rtfilerequest('RAM:',,"GEDCOM Input File")
end
else do
Tell("Please enter the filename (with complete path) of the GEDCOM file:")
TellNN("Input file: ")
pull inname
end
if inname = '' then
TermError("ERROR: No Input File!")
end
if ~open(infile, inname, "r") then
TermError("ERROR: Input file '"inname"' not found!")
if ~open(errfile, dbname||".err", "w") then
errfile = stdout
if ~usereq then
Tell("Be patient - this may take a while...")
/* Initialize line count, individual counter and family counter */
ink = GetNextLine()
if left(ink, 6) ~= "0 HEAD" then do
close(infile)
TermError("ERROR: Invalid beginning of file - not a valid GEDCOM format")
end
lvlstr = '0'; lvl = 1; atlvl = 1
IRNArr. = 0; FGRNArr. = 0
/* Read the "HEAD" section until we find something else of level "0" */
prstot = ""
ink = ParseHeader(atlvl)
GETPROGVERSION
prsr = RESULT
prsr = "Destination: Scion Genealogist "||prsr
if ~usereq then
Tell(prsr)
else
prstot = prstot||prsr||NL
prsr = "Dest. file: "||dbname
if ~usereq then
Tell(prsr)
else do
prstot=prstot||prsr||NL||NL||"Parsing will take a while - be patient."||,
NL||"Click to start parsing..."
rtezrequest(prstot,'_Continue','Converter Message:')
end
/* Now scan the following level "0" fields for individuals;
* skip the families, for the moment
*/
irn = 0
replay = 0
do while ~eof(infile)
lvlstr = word(ink, 1)
lvl = GetNumType(lvlstr)
if lvl = atlvl then do
tagstr = upper(word(ink, words(ink)))
if tagstr = "INDI" then do
nstr = strip(word(ink, 2),'B','@'||xrange('A','Z'))
if DATATYPE(nstr) = 'NUM' then do
tp = GGetIRN(nstr)
if tp ~= 0 then
writeln(errfile, "ERROR: Duplicate person encountered: "||nstr||" (IRN "||tp||")")
irn = irn + 1
ink = ParsePerson(nstr, lvl)
if ink ~= "" then replay = 1
end
else TermError("ERROR: Cannot determine the Individual Record Number!")
end
end
/* Skip all lines with level ~= current level (0) */
if replay = 0 then ink = GetNextLine()
else replay = 0
end
if ~usereq then do
Tell("Number of persons parsed: "||irn)
GETTOTALIRN
tot = RESULT
Tell("Total number of persons in the Scion database: "||tot)
end
/* Now rescan the entire file for families; I know it is quite
* inefficient this way, but it's better to add all the persons first,
* and then establish the relations...
*/
close(infile)
if ~open(infile, inname, "r") then
TermError("ERROR: Unable to read relations!")
if ~usereq then
Tell("Scanning file again to establish relations...")
lvlstr = '0'; lvl = 1; atlvl = 1
fgrn = 0
replay = 0
do while ~eof(infile)
if replay = 0 then ink = GetNextLine()
else replay = 0
lvlstr = word(ink, 1)
lvl = GetNumType(lvlstr)
if lvl = atlvl then do
tagstr = upper(word(ink, words(ink)))
if tagstr = "FAM" then do
nstr = strip(word(ink, 2),'B','@'||xrange('A','Z'))
if DATATYPE(nstr) = 'NUM' then do
fp = GGetFGRN(nstr)
if fp ~= 0 then
writeln(errfile, "ERROR: Duplicate family encountered: "||nstr||" (FGRN "||fp||")")
fgrn = fgrn + 1
ink = ParseFamily(nstr, lvl)
if ink ~= "" then replay = 1
end
else TermError("ERROR: Cannot determine the Family Group Record Number!")
end
else if tagstr = "TRLR" then do
close(infile)
GETTOTALFGRN
ftot = RESULT
if usereq then do
GETTOTALIRN
itot = RESULT
TermError("PARSING DONE:"||NL||"Number of persons parsed: "||irn||,
NL||"Total number of persons in the Scion database: "||itot||,
NL||"Number of families parsed: "||fgrn||,
NL||"Total number of families in the Scion database: "||ftot||,
NL||NL||"DON'T FORGET TO SAVE YOUR SCION FILE!!!")
end
else do
Tell("Number of families parsed: "||fgrn)
Tell("Total number of families in the Scion database: "||ftot)
TermError("DONE! DON'T FORGET TO SAVE YOUR SCION FILE!!!")
end
end
end
/* Skip all the fields at lvl ~= this level */
end
close(infile)
if ink ~= "0 TRLR" then
TermError("ERROR: Unexpected end of file")
else
TermError("ERROR: Trailer not recognized!")
ParseHeader: PROCEDURE EXPOSE infile prstot NL outp usereq
parse arg inilvl
do while ~eof(infile)
ins = GetNextLine()
if ins = "" then
TermError("ERROR: Unexpected end of file")
lvlstr = word(ins, 1)