/********************************************************************
 *                                                                  *
 *      CRISP - Custom Reduced Instruction Set Programmers Editor   *
 *                                                                  *
 *      (C) Paul Fox, 1989                                          *
 *                                                                  *
 *    Please See COPYLEFT notice.                                   *
 *                                                                  *
 ********************************************************************/
# include	"crisp.h"

# define    BRACKETS	"BEGINEND"
# define    SEARCHSTRING "{{{<|[~0-z]}begin{[~0-z]|$}}|{{<|[~0-z]}end{[~0-z]|$}}}"
void
f_m_b()
{
	string bracket, mbracket, s, s1;
	int	br_level, incr, fwd;
	    
	save_position();
	bracket = substr (ltrim(upper(read())),1,3);
	if (index(BRACKETS, bracket) == 0) 
	{
		if (re_search(SF_IGNORE_CASE, SEARCHSTRING) <= 0) 
                {
			beep();
			return;
		}
		bracket = substr (ltrim(upper(read())),1,3);
	}
	message("Locating matching bracket...");
	if ( bracket == "BEG" )
	{
	  fwd = 0;
	  incr = -1;
	  mbracket = "END";
	}					
	else
	{
	  fwd = 1;
	  incr = 1;
	  next_char(1);
	  mbracket = "BEGIN";
	}    
        s = SEARCHSTRING;	 
	s1 = "BEG";		      

	br_level = 1;
	while (br_level > 0) 
	{				 
	        if ( (incr == 1) && (fwd == 1) )
		{			     
/*   This is because otherwise matching br_level gets to one more than reqd  */
/*   in case of finding a matching BEGIN */
		  br_level = 0;
		  fwd = 2;
		}  
		if (fwd) 
		{
			prev_char();
			if (re_search(SF_IGNORE_CASE|SF_BACKWARDS, s) <= 0)
			{
/*				message("Not Found On Backward Search");  */
				break;
			}	
		}
		else 
		{
			next_char();
			if (re_search(SF_IGNORE_CASE, s) <= 0)
			{
/*				message("Not Found In Forward Search"); */
				break;
			}
		}
		if (substr (ltrim(upper(read())),1,3) == s1)
		{
			br_level -= incr;
			
		}
		else			    
		{
			br_level += incr;
		}
	}
	if (br_level) 
	{
		error("Matching %s not found.", mbracket);
		restore_position();
		beep();
		return;
	}
	else
	{
		restore_position(0);
		message("Matching %s found.", mbracket);
	}
}
