Files
mars-flaim/flaim/src/gdfind.cpp
dsandersoremutah c55dab446f Renamed version4 to flaim and version5 to xflaim
git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@7 0109f412-320b-0410-ab79-c3e0c5ffbbe6
2006-01-27 21:06:39 +00:00

143 lines
4.5 KiB
C++

//-------------------------------------------------------------------------
// Desc: Find a node in a GEDCOM tree structure.
// Tabs: 3
//
// Copyright (c) 1990-1993,1996-2000,2003,2005-2006 Novell, Inc. All Rights Reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the GNU General Public
// License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, contact Novell, Inc.
//
// To contact Novell about this file by physical or electronic mail,
// you may find current contact information at www.novell.com
//
// $Id: gdfind.cpp 12307 2006-01-19 15:06:34 -0700 (Thu, 19 Jan 2006) dsanders $
//-------------------------------------------------------------------------
#include "flaimsys.h"
/*API~*********************************************************************
Name : GedFind
Area : GEDCOM
Desc : Gets the nth occurance of the node with a matching tag number.
Continues, if necessary, thru a limited number of sibling sub-trees.
If "treeCnt" is GED_FOREST(0), it continues thru virtually all sub-trees.
matches occur without regard to path (always assumes leading wild card)
Note:
*END************************************************************************/
NODE *
// Returns a pointer to the nth occurance of the node with a matching
// tag or NULL if unsuccesful. If a value less than 0 is
// given for nth, the first value will be returned. If a
// value greater than the number of occurances is given,
// NULL will be returned.
GedFind(
FLMUINT treeCnt,
// [IN] Maximum number of sibling trees to search.
NODE * nd,
// [IN] GEDCOM tree or forest to search for matching tnum.
FLMUINT tnum,
// [IN] Specific tag number to find.
FLMINT nth
// [IN] The occurance of the tag number to find.
)
{
if( nd)
{
FLMUINT strtLvl = GedNodeLevel( nd); /* Starting level */
do
{
if( (tnum == GedTagNum( nd)) && (--nth < 1))
return( nd);
} while(
(nd = nd->next) != NULL &&
(
GedNodeLevel( nd) > strtLvl ||
(--treeCnt && GedNodeLevel( nd) == strtLvl)
)
);
}
return( NULL);
}
/*API~*********************************************************************
Name : GedNodeCopy
Area : GEDCOM
Desc : Gets the "nth" occurance of the node with a matching path of tag numbers.
This path may be found in the first tree only, the entire forest or
within the first "treeCnt" of trees.
Notes: This routine does not support any wildcard tags.
VISIT: This code has some bugs, one of which is that the
path array may be accessed past the null terminator.
*END************************************************************************/
NODE *
// Returns the nth occurance of the node at the end of the
//path or NULL if unsuccesful. If a value less than 0 is
//given for nth, the first value will be returned. If a
//value greater than the number of occurances is given,
//NULL will be returned.
GedPathFind(
FLMUINT treeCnt,
// [IN] Maximum number of sibling tress to search.
NODE * nd,
// [IN] The input GEDCOM tree to search for matching path.
FLMUINT * puiPathArray,
// [IN] A null terminated array of field numbers which make
// up a path.
FLMINT nth
// [IN] The occurance of the matching path to return. This
// value is usualy one.
)
{
NODE * node = nd;
NODE * savenode;
FLMUINT * path;
if( nd && puiPathArray)
{
FLMUINT uiLevel = GedNodeLevel( nd);
for(;;)
{
path = puiPathArray + (GedNodeLevel( node) - uiLevel);
savenode = node;
if( *path == GedTagNum( node)) /* matching piece of path */
{
if( *(path + 1) == 0 && (--nth < 1))
return( node); /* complete match found */
if( (node = GedChild( node)) != NULL)
continue; /* go down level for rest of path */
node = savenode;
}
do
{
node = node->next;
}
while( node != NULL &&
GedNodeLevel( node) > GedNodeLevel( savenode)); /* find next sibling/uncle/end */
if(
! node || /* end of tree */
GedNodeLevel( node) < uiLevel || /* end of forest */
(
GedNodeLevel( node) == uiLevel &&
!(--treeCnt) /* end of partial forest limit */
)
)
break;
}
}
return( NULL);
}