;** 
;**		BRIEF -- Basic Reconfigurable Interactive Editing Facility
;**
;**		Written by Dave Nanian and Michael Strickman.
;**
;**		Revision history:
;**		-----------------
;**

;**		brace.m:
;**
;**		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

(macro brace
	(
		(int			tot_count
						start_line
						start_col
						mismatch
						char_we_got
						backward
		)
		(string		msg_pattern
						msg_text)

		(= msg_pattern "Checking braces, %d unmatched {s.")
		(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)
			)
		)
	)
)

(macro char_search
	(
		(int			backward)

		(get_parm 0 backward)

		(if backward
			(returns (search_back "[\\{\\}]"))
		;else
			(returns (search_fwd "[\\{\\}]"))
		)
	)
)
