/*
**		BRIEF -- Basic Reconfigurable Interactive Editing Facility
**
**		Written by Dave Nanian and Michael Strickman.
*/

/*		brace.cb:
**
**		This macro is an attempt at a "locate the unmatched brace" utility.
**	Although it attempts to be fairly smart about things, it has an IQ of
**	4 or 5, so be careful before taking its word for something.
**
**		It DOES NOT WORK if there are braces inside quotes, apostrophes, or
**	comments.  The macro can, however, be modified to ignore everything
**	inside these structures (and check for the appropriate mismatches).
*/

#define TRUE	  1
#define BACK	  1
#define DONE	  2

int char_search (int backward);

void brace ()
{
	int	tot_count,
			start_line,
			start_col,
			mismatch,
			char_we_got,
			backward;

	string	msg_pattern = "Checking braces, %d unmatched {s.",
				msg_text;

	inq_position (start_line, start_col);
	top_of_buffer ();

	while (backward < DONE)
		{
		while (char_search (backward) && !mismatch)
			{
			sprintf (msg_text, msg_pattern, tot_count);
			message (msg_text);

			if (backward)
				char_we_got = index ("}{", read (1));
			else
				char_we_got = index ("{}", read (1));

			if (char_we_got == 1)
				++tot_count;
			else if (char_we_got == 2)
				if (tot_count)
					--tot_count;
				else
					{
					if (backward)
						message ("Mismatched opening brace.");
					else
						message ("Mismatched closing brace.");

					mismatch = TRUE;
					}
			if (!mismatch)
				if (backward)
					prev_char ();
				else
					next_char ();
			}
		if (!mismatch)
			if (tot_count)
				{
				end_of_buffer ();
				tot_count = 0;
				backward = BACK;
				msg_pattern = "Locating mismatch, %d unmatched }s.";
				}
			else
				backward = DONE;
		else
			backward = DONE;
		}
	if (!mismatch)
		{
		message ("All braces match.");
		move_abs (start_line, start_col);
		}
}

int char_search (int backward)
{
	if (backward)
		returns (search_back ("[\\{\\}]"));
	else
		returns (search_fwd ("[\\{\\}]"));
}
