/* ===========================================================================
*
*                            PUBLIC DOMAIN NOTICE
*               National Center for Biotechnology Information
*
*  This software/database is a "United States Government Work" under the
*  terms of the United States Copyright Act.  It was written as part of
*  the author's official duties as a United States Government employee and
*  thus cannot be copyrighted.  This software/database is freely available
*  to the public for use. The National Library of Medicine and the U.S.
*  Government have not placed any restriction on its use or reproduction.
*
*  Although all reasonable efforts have been taken to ensure the accuracy
*  and reliability of the software and data, the NLM and the U.S.
*  Government do not and cannot warrant the performance or results that
*  may be obtained by using this software or data. The NLM and the U.S.
*  Government disclaim all warranties, express or implied, including
*  warranties of performance, merchantability or fitness for any particular
*  purpose.
*
*  Please cite the author in any work or product based on this material.
*
* ===========================================================================*/

#include <ncbi.h>
#include <dfa.h>

/*************************************************************************
 *	dfa_sscanf(dp, query, querylen, report)
 *
 *	Use the specified DFA to parse the query string and report matches.
 *
 *	The query string is _not_ interpreted as a NUL-terminated C string.
 *************************************************************************/
DFA_Error _cdecl
dfa_sscanf(dp, query, querylen, report)
	DFAPtr	dp;
	CharPtr	query;	/* The input */
	size_t	querylen;	/* Max. no. of letters to examine in query */
	/* Call-back function to report matches */
	int	(_cdecl *report) PROTO((size_t off, DFA_PatID patID));
{
	DFA_StatePtr	S;
	CharPtr	querymax, query0 = query;
	DFA_AcceptPtr	ap;
	DFA_PatlistPtr	plp;

	if (dfa_opstate(dp) != dfaOpstateClosed)
		return dfaerrno = dfaErrOpstate;
	if (dp->xlen != 0)
		return dfaerrno = dfaErrIncompat;

	if (report == NULL || query == NULL)
		return dfaerrno = dfaErrNullParm;

	querymax = &query[querylen];
	S = dp->state0;

	for (; query < querymax; ++query) {
		while (!DFA_ISACCEPTING(S = S->next[*query])) {
			if (++query >= querymax)
				return dfaErrNone;
		}
		if ((ap = (DFA_AcceptPtr)DFA_UNMUNGED(S)) == NULL)
			return dfaErrNone;
		S = ap->retState;
		plp = &ap->pl;
		do {
			if ((*report)(query-query0, plp->patID) != 0)
				return dfaErrReport;
		} while ((plp = plp->chain) != NULL);
	}
	return dfaErrNone;
}
