#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;
}

