Пример #1
0
        public override void PostCheck(GEDCommon rec)
        {
            var me = rec as IndiRecord;

            if (string.IsNullOrWhiteSpace(me.Ident))
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.MissIdent; // TODO "INDI missing identifier"; // TODO assign one?
                err.Beg   = err.End = me.BegLine;
                err.Tag   = rec.Tag;
                me.Errors.Add(err);
            }

            // TODO should this be checked in the SEX routine so line # points at the actual line???
            // Make sure sex is set
            if (me.Sex != '\0')
            {
                if (!"MFUmfu".Contains(me.Sex.ToString(CultureInfo.InvariantCulture)))
                {
                    me.Sex = 'U';

                    UnkRec err = new UnkRec();
                    err.Error = UnkRec.ErrorCode.InvSex; // "Non-standard SEX value corrected to U";
                    err.Beg   = err.End = me.BegLine;
                    me.Errors.Add(err);                  // TODO as warning
                }
            }
            CheckRestriction(me, me.Restriction);

            // TODO check restriction value on events
        }
Пример #2
0
        public static void ChanProc(ParseContext2 ctx)
        {
            ChangeRec chan = ctx.Parent.CHAN;

            if (chan.Date != null)
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.MultChan;
                GedRecParse.LookAhead(ctx);
                err.Beg = ctx.Begline + ctx.Parent.BegLine;
                err.End = ctx.Endline + ctx.Parent.BegLine;
                ctx.Parent.Errors.Add(err);
                return;
            }

            ChanParse(ctx, chan);
            if (chan.Date == null)
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.ChanDate;
                err.Beg   = ctx.Begline + ctx.Parent.BegLine;
                err.End   = ctx.Endline + ctx.Parent.BegLine;
                ctx.Parent.Errors.Add(err);
            }
        }
Пример #3
0
        public override void PostCheck(GEDCommon rec)
        {
            MediaRecord me = rec as MediaRecord;

            if (string.IsNullOrWhiteSpace(me.Ident))
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.MissIdent; // TODO "Missing identifier"; // TODO assign one?
                err.Beg   = err.End = me.BegLine;
                me.Errors.Add(err);
            }

            // A FILE record is required
            if (me.Files.Count < 1)
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.MissFile; // "Missing FILE";
                err.Beg   = err.End = me.BegLine;
                me.Errors.Add(err);
            }

            // Each FILE record must have a FORM
            foreach (var mediaFile in me.Files)
            {
                if (string.IsNullOrWhiteSpace(mediaFile.Form))
                {
                    UnkRec err = new UnkRec();
                    err.Error = UnkRec.ErrorCode.MissForm; // "Missing FORM";
                    err.Beg   = err.End = me.BegLine;
                    me.Errors.Add(err);
                }
            }
        }
Пример #4
0
        private void nchiProc(ParseContext2 context)
        {
            // TODO Data loss: The Master Genealogist (TMG) treats NCHI as a text field.
            // NCHI in TMG can have CONC, CONT, and other sub-tags. Here, these sub-tags
            // are not correctly connected to the NCHI tag, nor am I preserving the NCHI
            // data as entered.

            var fam = (context.Parent as FamRecord);

            int childCount;

            if (!int.TryParse(context.Remain, out childCount))
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.InvNCHI; //"Invalid child count";
                err.Beg   = err.End = context.Begline + context.Parent.BegLine;
                fam.Errors.Add(err);
            }
            else if (fam.ChildCount != -1) // has been specified once already
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.MultNCHI;
                //err.Error = "Child count specified more than once";
                err.Beg = err.End = context.Begline + context.Parent.BegLine;
                fam.Errors.Add(err);
            }
            else
            {
                fam.ChildCount = childCount;
            }
        }
Пример #5
0
        public static AssoRec AssoParse(ParseContext2 ctx)
        {
            var asso = new AssoRec();

            string xref;
            string extra;

            parseXrefExtra(ctx.Remain, out xref, out extra);

            if (string.IsNullOrEmpty(xref))
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.UntermIdent;
                // TODO err.Error = "Missing/unterminated identifier: " + ctx.Tag;
                err.Beg = err.End = ctx.Begline + ctx.Parent.BegLine;
                err.Tag = ctx.Tag;
                ctx.Parent.Errors.Add(err); // TODO parent level or structure level?
            }
            else
            {
                asso.Ident = xref;
            }
            //StructParseContext ctx2 = new StructParseContext(ctx, asso);
            StructParseContext ctx2 = PContextFactory.Alloc(ctx, asso);

            StructParse(ctx2, tagDict);
            ctx.Endline = ctx2.Endline;
            PContextFactory.Free(ctx2);
            return(asso);
            // TODO validate relation specified
            // TODO validate ident existance
        }
Пример #6
0
        public override void PostCheck(GEDCommon rec)
        {
            var me = rec as NoteRecord;

            if (string.IsNullOrWhiteSpace(me.Ident))
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.MissIdent; // TODO {Error = "Missing identifier"};
                err.Beg   = err.End = me.BegLine;
                me.Errors.Add(err);
            }

            if (me.Builder.Length > 0)
            {
                // Store an in-line note to the database
                string text = me.Builder.ToString().Replace("@@", "@");
#if SQLITE
                me.Key = SQLite.Instance.StoreNote(text);
#elif LITEDB
                me.Key = LiteDB.Instance.StoreNote(text);
#elif NOTESTREAM
                me.Key = NoteStream.Instance.StoreNote(text);
#else
                me.Text = text;
#endif
            }
            else
            {
                me.Text = "";
            }

            //me.Text = me.Builder.ToString().Replace("@@", "@"); // TODO faster replace
            me.Builder = null;
        }
Пример #7
0
        // Common method for unit testing (instream != null) or file reading (gedPath != null)
        /// <summary>
        /// Read GEDCOM data into memory.
        /// </summary>
        /// <param name="gedPath">The path to the file. If null, will attempt to read from instream instead.</param>
        /// <param name="instream">An input stream to read from instead of a file path.</param>
        public void ReadGed(string gedPath, StreamReader instream = null)
        {
            _emptyLineSeen = 0;
            FilePath       = gedPath;
            Errors         = new List <UnkRec>();
            GedReader _reader = new GedReader();

            _reader.BufferSize   = _bufferSize;
            _reader.ProcessALine = ProcessLine;
            _reader.ErrorTracker = DoError;

            // Processor context
            Parser = new GedParser(FilePath);
            Data   = new List <GEDCommon>();
            if (Errors == null)
            {
                Errors = new List <UnkRec>();
            }
            _currRec = new GedRecord();
#if SQLITE
            var foo = SQLite.Instance;
#elif LITEDB
            var foo = SharpGEDParser.Parser.LiteDB.Instance;
#elif NOTESTREAM
            var foo = NoteStream.Instance;
#endif
#if XREFTRACK
            var bar = XrefTrack.Instance;
#endif
            try
            {
                if (gedPath == null)
                {
                    _reader.ReadFile(instream);
                }
                else
                {
                    _reader.ReadFile(gedPath);
                }
                EndOfFile();
            }
            catch (Exception)
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.Exception;
                err.Beg   = _lineNum;
                // TODO err.Error = string.Format("Exception: {0} line {1} | {2}", ex.Message, _lineNum, ex.StackTrace);
                Errors.Add(err);
            }

            Parser.FinishUp();
            GatherRecords();
            GatherErrors();

            _lineNum = _reader._lineNum;
            _currRec = null;
        }
Пример #8
0
        private void DoError(UnkRec.ErrorCode msg, int lineNum)
        {
            var err = new UnkRec();

            err.Error = msg;
            err.Beg   = lineNum;
            err.End   = lineNum;
            Errors.Add(err);
        }
Пример #9
0
 private StringPlus CheckAndMakeId(ParseContext2 ctx, StringPlus who)
 {
     if (who != null)
     {
         var rec = new UnkRec(ctx.Tag, ctx.Begline + ctx.Lines.Beg, ctx.Endline + ctx.Lines.Beg);
         rec.Error = UnkRec.ErrorCode.MultId;
         ctx.Parent.Errors.Add(rec);
         return(who);
     }
     return(makeId(ctx));
 }
Пример #10
0
        private static SourceCit CommonParser(ParseContextCommon ctx, int linedex, char level, List <UnkRec> errs)
        {
            SourceCit          cit  = new SourceCit();
            StructParseContext ctx2 = new StructParseContext(ctx, linedex, level, cit); // TODO no record for context!

            string extra;
            string xref;

            parseXrefExtra(ctx.Remain, out xref, out extra);

            cit.Xref = xref;
            if (xref != null && (xref.Trim().Length == 0 || cit.Xref.Contains("@")))  // No xref is valid but not if empty/illegal
            {
                var unk = new UnkRec();
                unk.Error = UnkRec.ErrorCode.InvXref; // TODO {Error = "Invalid source citation xref id"};
                unk.Beg   = ctx.Begline + ctx.Lines.Beg;
                unk.End   = ctx.Endline + ctx.Lines.Beg;
                errs.Add(unk);
            }
            if (!string.IsNullOrEmpty(extra))
            {
                cit.Desc = extra;
            }

            StructParse(ctx2, tagDict);
            ctx.Endline = ctx2.Endline;

            if (!cit.Data && cit.Xref != null && cit.AnyText)
            {
                var unk = new UnkRec();
                unk.Error = UnkRec.ErrorCode.RefSourText; // TODO { Error = "TEXT tag used for reference source citation" };
                unk.Beg   = ctx.Begline + ctx.Lines.Beg;
                unk.End   = ctx2.Endline + ctx.Lines.Beg;
                errs.Add(unk);
            }
            if (cit.Xref == null && cit.Event != null)
            {
                var unk = new UnkRec();
                unk.Error = UnkRec.ErrorCode.EmbSourEven; // TODO { Error = "EVEN tag used for embedded source citation" };
                unk.Beg   = ctx.Begline + ctx.Lines.Beg;
                unk.End   = ctx2.Endline + ctx.Lines.Beg;
                errs.Add(unk);
            }
            if (cit.Xref == null && cit.Page != null)
            {
                var unk = new UnkRec();
                unk.Error = UnkRec.ErrorCode.EmbSourPage; // TODO { Error = "PAGE tag used for embedded source citation" };
                unk.Beg   = ctx.Begline + ctx.Lines.Beg;
                unk.End   = ctx.Endline + ctx.Lines.Beg;
                errs.Add(unk);
            }
            return(cit);
        }
Пример #11
0
        private void PopulateLineList(int type, object data)
        {
            listBox2.SuspendLayout();
            listBox2.Items.Clear(); // TODO delay update?
            richTextBox1.ResetText();

            if (type != ISS)
            {
                var   foo   = data as List <atup2>;
                atup2 first = foo[0];
                if (type == ERR)
                {
                    textBox1.Text = string.Format("Error: {0}{2}, Count:{1}", first.Item1.Error, foo.Count,
                                                  string.IsNullOrEmpty(first.Item1.Tag) ? "" : ", Tag:" + first.Item1.Tag);
                }
                else
                {
                    textBox1.Text = string.Format("Unknown: {0}, Count:{1}", first.Item1.Tag, foo.Count);
                }

                foreach (var tuple in foo)
                {
                    UnkRec       unk  = tuple.Item1;
                    string       val  = string.Format("Lines:{0}-{1}", unk.Beg, unk.End);
                    ListBoxItem2 lbi2 = new ListBoxItem2();
                    lbi2.txt = val;
                    lbi2.err = unk;
                    lbi2.rec = tuple.Item2;
                    listBox2.Items.Add(lbi2);
                }
            }
            else
            {
                var   foo   = data as List <Issue>;
                Issue first = foo[0];
                textBox1.Text = string.Format("Issue: {0}, Count:{1}", first.IssueId, foo.Count);
                foreach (var iss in foo)
                {
                    string       val  = iss.Message();
                    ListBoxItem2 lbi2 = new ListBoxItem2();
                    lbi2.txt = val;
                    lbi2.rec = null; // TODO need record link
                    lbi2.iss = iss;
                    listBox2.Items.Add(lbi2);
                }
            }

            if (listBox2.Items.Count > 0)
            {
                listBox2.SelectedIndex = 0;
            }
            listBox2.ResumeLayout();
        }
Пример #12
0
        public override void PostCheck(GEDCommon rec)
        {
            SourceRecord me = rec as SourceRecord;

            if (string.IsNullOrWhiteSpace(me.Ident)) // TODO common?
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.MissIdent; // TODO {Error = "Missing identifier"};
                err.Beg   = err.End = rec.BegLine;
                me.Errors.Add(err);
            }

            // No required data except Xref id?
            // TODO Warning: no data provide
        }
Пример #13
0
        public static IndiLink LinkParse(ParseContext2 ctx)
        {
            UnkRec err = null;

            IndiLink link = new IndiLink();

            // Can't get here for values other than FAMC/FAMS [unless caller changes!]
            link.Type = ctx.Tag == "FAMC" ? IndiLink.FAMC_TYPE : IndiLink.FAMS_TYPE;

            string xref;
            string extra;

            parseXrefExtra(ctx.Remain, out xref, out extra);

            if (string.IsNullOrEmpty(xref))
            {
                err       = new UnkRec();
                err.Error = UnkRec.ErrorCode.MissIdent;
                err.Beg   = err.End = ctx.Begline + ctx.Parent.BegLine;
                err.Tag   = ctx.Tag;
                ctx.Parent.Errors.Add(err);
            }
            else
            {
                link.Xref = xref;
            }

            if (!string.IsNullOrEmpty(extra))
            {
                link.Extra = extra;
            }

            //StructParseContext ctx2 = new StructParseContext(ctx, link);
            StructParseContext ctx2 = PContextFactory.Alloc(ctx, link);

            StructParse(ctx2, tagDict);
            ctx.Endline = ctx2.Endline;
            PContextFactory.Free(ctx2);

            if (err != null)
            {
                // Fallout from GedValid: an error in the link should not create an IndiLink
                err.End = ctx.Endline + ctx.Parent.BegLine; // entire structure in error
                return(null);
            }

            return(link);
        }
Пример #14
0
        private void resnProc(ParseContext2 context)
        {
            var fam = (context.Parent as FamRecord);

            if (string.IsNullOrEmpty(fam.Restriction))
            {
                fam.Restriction = context.Remain.Trim();
            }
            else
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.MultRESN; // TODO "RESN specified more than once";
                err.Beg   = err.End = context.Begline + context.Parent.BegLine;
                fam.Errors.Add(err);
            }
        }
Пример #15
0
        protected static string parseForXref(ParseContext2 context, UnkRec.ErrorCode errVal = UnkRec.ErrorCode.MissIdent)
        {
            string xref;
            string extra;

            StructParser.parseXrefExtra(context.Remain, out xref, out extra);
            if (string.IsNullOrEmpty(xref))
            {
                UnkRec err = new UnkRec();
                err.Error = errVal;
                err.Beg   = err.End = context.Begline + context.Parent.BegLine;
                err.Tag   = context.Tag;
                context.Parent.Errors.Add(err);
            }
            return(xref);
        }
Пример #16
0
        private void resnProc(ParseContext2 context)
        {
            var indi = (context.Parent as IndiRecord);

            if (string.IsNullOrEmpty(indi.Restriction))
            {
                indi.Restriction = context.Remain.Trim();
            }
            else
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.MultRESN; // "RESN specified more than once";
                err.Beg   = err.End = context.Begline;
                indi.Errors.Add(err);
            }
        }
Пример #17
0
        protected void UidProc(ParseContext2 ctx)
        {
            if (ctx.Parent._uid != null)
            {
                var rec = new UnkRec(ctx.Tag, ctx.Begline + ctx.Lines.Beg, ctx.Endline + ctx.Lines.Beg);
                rec.Error = UnkRec.ErrorCode.MultId;
                ctx.Parent.Errors.Add(rec);
                return;
            }
            int len = ctx.Remain1.Length;

            ctx.Parent._uid = new byte[len];
            for (int i = 0; i < len; i++)
            {
                ctx.Parent._uid[i] = (byte)ctx.Remain1[i];
            }
        }
Пример #18
0
        public static void NonStandardRemain(string remain, GEDCommon rec)
        {
            // Extra text on the record line (e.g. "0 @R1@ REPO blah blah blah") is not standard for
            // most record types. Preserve it as a note if possible.
            if (!string.IsNullOrWhiteSpace(remain))
            {
                UnkRec err = new UnkRec();
                err.Beg   = err.End = rec.BegLine;
                err.Error = UnkRec.ErrorCode.InvExtra;
                rec.Errors.Add(err);

                if (rec is NoteHold)
                {
                    Note not = new Note();
                    not.Text = remain;
                    (rec as NoteHold).Notes.Add(not);
                }
            }
        }
Пример #19
0
        public override void PostCheck(GEDCommon rec)
        {
            var me = rec as FamRecord;

            if (string.IsNullOrWhiteSpace(me.Ident))
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.MissIdent; // "Missing identifier"; // TODO assign one?
                err.Beg   = err.End = me.BegLine;
                err.Tag   = rec.Tag;
                me.Errors.Add(err);
            }

            // TODO NCHI value doesn't match # of CHIL refs?

            CheckRestriction(me, me.Restriction);

            // TODO check restriction value on events
        }
Пример #20
0
        public static NameRec Parse(ParseContext2 ctx)
        {
            // TODO can this be shortcut when context length is only 1 line?
            var name = new NameRec();

            if (!parseName(name, ctx.Remain1, ctx.Begline, ctx.Parent.Errors))
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.EmptyName;
                err.Beg   = err.End = ctx.Begline;
                ctx.Parent.Errors.Add(err);
            }
            //StructParseContext ctx2 = new StructParseContext(ctx, name);
            var ctx2 = PContextFactory.Alloc(ctx, name);

            StructParse(ctx2, tagDict);
            ctx.Endline = ctx2.Endline;
            PContextFactory.Free(ctx2);
            return(name);
        }
Пример #21
0
        public override void PostCheck(GEDCommon rec)
        {
            Repository me = rec as Repository;

            if (string.IsNullOrWhiteSpace(me.Ident))
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.MissIdent; // TODO {Error = "REPO missing identifier"};
                err.Beg   = err.End = me.BegLine;
                me.Errors.Add(err);
            }

            // A NAME record is required
            if (string.IsNullOrWhiteSpace(me.Name))
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.MissName; // TODO {Error = "REPO missing identifier"};
                err.Beg   = err.End = me.BegLine;
                me.Errors.Add(err);
            }
        }
Пример #22
0
        private static void xrefproc(StructParseContext context, int linedex, char level)
        {
            var me = (context.Parent as LDSEvent);

            // TODO copy-pasta from IndiParse
            string xref;
            string extra;

            parseXrefExtra(context.Remain, out xref, out extra);
            if (string.IsNullOrEmpty(xref))
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.UntermIdent; // TODO "Missing/unterminated identifier: " + context.Tag;
                err.Beg   = err.End = context.Begline;
                context.Record.Errors.Add(err);           // TODO is Record only for errors?
            }
            else
            {
                me.FamilyXref = xref;
            }
        }
Пример #23
0
        // Common processing for SUBM, HUSB, WIFE
        private void xrefProc(ParseContext2 context)
        {
            // TODO how are sub-tags handled? E.g. _PREF on HUSB, WIFE

            string xref = parseForXref(context);
            var    fam  = (context.Parent as FamRecord);

            if (!string.IsNullOrEmpty(xref))
            {
                switch (context.Tag)
                {
                case "HUSB":
                    if (fam.Dads.Count != 0)     // HUSB already specified
                    {
                        UnkRec err = new UnkRec();
                        err.Error = UnkRec.ErrorCode.MultHUSB;     //"HUSB line used more than once";
                        err.Beg   = err.End = context.Begline + context.Parent.BegLine;
                        fam.Errors.Add(err);
                    }
                    fam.Dads.Add(xref);
                    break;

                case "WIFE":
                    if (fam.Moms.Count != 0)     // WIFE already specified
                    {
                        UnkRec err = new UnkRec();
                        err.Error = UnkRec.ErrorCode.MultWIFE;     //"WIFE line used more than once";
                        err.Beg   = err.End = context.Begline + context.Parent.BegLine;
                        fam.Errors.Add(err);
                    }
                    fam.Moms.Add(xref);
                    break;

                case "SUBM":
                    fam.FamSubm.Add(xref);     // TODO check if xref specified more than once
                    break;
                }
            }
        }
Пример #24
0
        public void CheckRestriction(GEDCommon rec, string restrict)
        {
            // Common post-processing restriction checking
            if (string.IsNullOrWhiteSpace(restrict)) // nothing specified, nothing to do
            {
                return;
            }
            switch (restrict.ToLowerInvariant())
            {
            case "confidential":
            case "locked":
            case "privacy":
                break;

            default:
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.InvRestrict;
                err.Beg   = err.End = rec.BegLine;
                rec.Errors.Add(err);
                break;
            }
        }
Пример #25
0
        public static RepoCit CitParser(ParseContext2 ctx)
        {
            RepoCit cit = new RepoCit();
            //StructParseContext ctx2 = new StructParseContext(ctx, cit);
            var ctx2 = PContextFactory.Alloc(ctx, cit);

            string extra;
            string xref;

            parseXrefExtra(ctx.Remain, out xref, out extra);

            if (string.IsNullOrEmpty(xref))
            {
                cit.Xref = null;
            }
            else
            {
                cit.Xref = xref;
            }

            if (xref != null && (xref.Trim().Length == 0 || cit.Xref.Contains("@"))) // NOTE: missing xref is valid, but NOT empty one!
            {
                UnkRec unk = new UnkRec();
                unk.Error = UnkRec.ErrorCode.InvXref;
                ctx.Parent.Errors.Add(unk);
                // TODO ctx.Parent.Errors.Add(new UnkRec { Error = "Invalid repository citation xref id" }); // TODO not yet reproduced in the field
                // TODO error line #s
            }
            if (!string.IsNullOrEmpty(extra))
            {
                addNote(cit, extra);
            }

            StructParse(ctx2, tagDict);
            ctx.Endline = ctx2.Endline;
            PContextFactory.Free(ctx2);
            return(cit);
        }
Пример #26
0
        // CHIL processing pulled out for _FREL/_MREL
        private void childProc(ParseContext2 context)
        {
            var fam = (context.Parent as FamRecord);

            LookAhead(context); // Any sub-lines (e.g. _FREL/_MREL)?

            string xref;
            string extra;

            StructParser.parseXrefExtra(context.Remain, out xref, out extra);
            if (string.IsNullOrEmpty(xref))
            {
                UnkRec err = new UnkRec();
                err.Error = UnkRec.ErrorCode.MissIdent; // TODO "Missing/unterminated identifier: " + context.Tag;
                err.Beg   = context.Begline + context.Parent.BegLine;
                err.End   = context.Endline + context.Parent.BegLine;
                err.Tag   = context.Tag;
                fam.Errors.Add(err);
                return;
            }
#if XREFTRACK
            int key = XrefTrack.Instance.StoreXref(xref);
#endif
            foreach (var child in fam.Childs)
            {
#if XREFTRACK
                if (child.Key == key)
#else
                if (child.Xref == xref)
#endif
                {
                    UnkRec err = new UnkRec();
                    err.Error = UnkRec.ErrorCode.MultCHIL; // TODO "CHIL ident used more than once (one person cannot be two children)";
                    err.Beg   = context.Begline + context.Parent.BegLine;
                    err.End   = context.Endline + context.Parent.BegLine;
                    fam.Errors.Add(err);
                    return;
                }
            }

            string mrel = null;
            string frel = null;
            if (context.Endline > context.Begline)
            {
                LineUtil.LineData ld = new LineUtil.LineData();
                //var gs = new GEDSplitter();
                //ParseContext2 ctx = new ParseContext2();
                int i = context.Begline + 1;
                while (i <= context.Endline)
                {
                    //LineUtil.LevelTagAndRemain(ld, context.Lines.GetLine(i));
                    context.gs.LevelTagAndRemain(context.Lines.GetLine(i), ld);
                    switch (ld.Tag)
                    {
                    case "_MREL":
                        if (!string.IsNullOrWhiteSpace(ld.Remain))     // FTA expects 'Natural' and I canna see why not && ld.Remain != "Natural")
                        {
                            mrel = ld.Remain;
                        }
                        break;

                    case "_FREL":
                        if (!string.IsNullOrWhiteSpace(ld.Remain))     // FTA expects 'Natural' and I canna see why not && ld.Remain != "Natural")
                        {
                            frel = ld.Remain;
                        }
                        break;

                    case "_PREF":
                    case "_STAT":
                        // TODO temporarily ignore: see 2524482.ged
                        break;

                    default:
                        UnkRec unk = new UnkRec(ld.Tag, i + context.Parent.BegLine, i + context.Parent.BegLine);
                        fam.Unknowns.Add(unk);
                        break;
                    }
                    i++;
                }
                //gs = null;
            }
            fam.AddChild(xref, frel, mrel);
        }
Пример #27
0
        private static bool parseName(NameRec rec, char[] line, int linenum, List <UnkRec> errors)
        {
            int max = line.Length;

            // BOULDER_CEM_02212009b.GED had a "1 NAME" with nothing else
            int startName = LineUtil.FirstChar(line, 0, max);

            if (startName < 0)
            {
                return(false);
            }

            // Deal with slashes in the surname
            int startSur = LineUtil.AllCharsUntil(line, max, startName, '/');
            int endSur   = LineUtil.ReverseSearch(line, max, startSur + 1, '/');

            var suffix = "";

            if (endSur + 1 < max)
            {
                //suffix = string.Join(" ", line.Substring(endSur + 1).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); // Remove extra spaces
                int newlen = 0;
                var tmp    = LineUtil.RemoveExtraSpaces(line, endSur + 1, max, ref newlen);
                //suffix = _nameCache.GetFromCache(tmp, 0, newlen).Trim(); // TODO trim
                suffix = new string(tmp, 0, newlen).Trim();
            }

            {
                int a = 0;
                int b = max;
                if (startSur < max)
                {
                    a = startName;
                    b = startSur - startName;
                }
                int newlen = 0;
                var tmp    = LineUtil.RemoveExtraSpaces(line, a, b, ref newlen);
                //rec.Names = _nameCache.GetFromCache(tmp, a, newlen).Trim(); // TODO trim
                rec.Names = new string(tmp, a, newlen).Trim();
            }

            // Observed bug from ege.ged: empty surname was not parsed properly
            int surnameLen = endSur - startSur - 2; // Will be zero if empty, e.g. "1 NAME Liz //"

            if (startSur < max && surnameLen > 0)   // e.g. "1 NAME LIVING"
            {
                //rec.Surname = line.Substring(startSur + 1, endSur - startSur - 1).Trim();
                //rec.Surname = _surnameCache.GetFromCache(line, startSur + 1, endSur - startSur - 1).Trim();// TODO trim
                rec.Surname = new string(line, startSur + 1, endSur - startSur - 1).Trim();
                if (rec.Surname.Contains("/"))
                {
                    UnkRec err = new UnkRec();
                    err.Beg   = err.End = linenum;
                    err.Error = UnkRec.ErrorCode.SlashInName;
                    errors.Add(err);
                }
                if (endSur == max && startSur < max)
                {
                    UnkRec err = new UnkRec();
                    err.Beg   = err.End = linenum;
                    err.Error = UnkRec.ErrorCode.UntermSurname;
                    errors.Add(err);
                }
            }
            if (suffix.Length > 0)
            {
                rec.Suffix = suffix;
            }
            return(true);
        }
Пример #28
0
        protected static void StructParse(StructParseContext ctx, Dictionary <string, TagProc> tagSet)
        {
            LineUtil.LineData ld = new LineUtil.LineData();
            //GEDSplitter gs = new GEDSplitter();

            int i   = ctx.Begline + 1;
            int max = ctx.Lines.Max;

            for (; i < max; i++)
            {
                try
                {
                    ctx.gs.LevelTagAndRemain(ctx.Lines.GetLine(i), ld);
                    //LineUtil.LevelTagAndRemain(ld, ctx.Lines.GetLine(i));
                }
                catch (Exception)
                {
                    UnkRec exc = new UnkRec();
                    exc.Beg   = exc.End = i;
                    exc.Error = UnkRec.ErrorCode.Exception;
                    // TODO exc.Error = "Exception during parse, skipping line";
                    ctx.Record.Errors.Add(exc); // TODO is Record only for errors?
                    continue;
                }

                if (ld.Level <= ctx.Level)
                {
                    break; // end of sub-record
                }
                ctx.Remain1 = ld.Remain1;

                if (ld.Tag == null)
                {
                    UnkRec exc = new UnkRec();
                    exc.Beg   = exc.End = i;
                    exc.Error = UnkRec.ErrorCode.MissTag;
                    // TODO exc.Error = "Exception during parse, skipping line";
                    // TODO not exception - missing tag / invalid linebreak
                    ctx.Record.Errors.Add(exc); // TODO is Record only for errors?
                    continue;
                }

                TagProc tagproc;
                if (tagSet.TryGetValue(ld.Tag, out tagproc))
                {
                    ctx.Begline = i;
                    ctx.Tag     = ld.Tag;
                    tagproc(ctx, i, ld.Level);
                }
                else
                {
                    LineSet extra    = new LineSet();
                    char    oldLevel = ctx.Level;
                    ctx.Begline = i;
                    ctx.Level   = ld.Level;
                    GedRecParse.LookAhead(ctx);
                    extra.Beg = ctx.Begline + ctx.Lines.Beg; // Make line #s relative to file
                    extra.End = ctx.Endline + ctx.Lines.Beg;
                    ctx.Parent.OtherLines.Add(extra);
                    ctx.Level = oldLevel;
                }
                i = Math.Max(ctx.Endline, i); // HACK: extendedText() may have advanced ctx.Endline further
            }
            ctx.Endline = i - 1;
            ld          = null;
            //gs = null;
        }