macro_file DBASE;
/*******************************************************************************
														MULTI-EDIT MACRO FILE

Name: DBASE

Description:  Contains language support for DBase style languages.

DBAMTCH - Construct matching for DBase
DBA_IND - Smart indenting for DBase
DBATEMP - Template editing for DBase

							 (C) Copyright 1991 by American Cybernetics, Inc.
********************************************************************************/

macro DBAMTCH TRANS {
/*******************************************************************************
																MULTI-EDIT MACRO

 Name: DBAMTCH

 Description:  This macro will match occurences of
		 IF / ENDIF, CASE / ENDCASE, DO WHILE / ENDDO, TEXT / ENDTEXT, ( / )
							 (C) Copyright 1991 by American Cybernetics, Inc.
													 Contributed by Julius Nadas
*******************************************************************************/

	str  Str1, Str2, S_var,            /* Match strings */
					 Xtr2,
					 T_Str, S_str, FStr ;

	int  Direction,   /* 1 = search forward, 0 = backward */
					 B_Count,     /* Match count.  0 = match found */
					 I_var,       /* just a temp variable */
					 temp_case,   /* save ignore_case flag */
					 S_Res;      /* Search result */

	Refresh = False;     /* Turn screen refresh off */
	temp_case = ignore_case;
	ignore_case = true;

	Mark_Pos;             /*  return here if no find  */

	if(  (Cur_Char == '(')  ) {   /* Setup match for '(' */
		Str1 = '(';
		Xtr2 = ')';
		Str2 = ')';
		Direction = 1;
		S_Str = '(||)||$';
		GOTO Start_Match;
	}

	if(  (Cur_Char == ')')  ) {   /* Setup match for ')' */
		Str1 = ')';
		Xtr2 = '(';
		Str2 = '(';
		Direction = 0;
		S_Str = Str1+'||'+Str2+'||%';
		GOTO Start_Match;
	}

 /* go to the first word */
	goto_col(1);

Match_Construct:

	if(XPos(Cur_Char,'|9|255 ',1)) {      /* If we are on a blank space then find a word */
		forward_till_not('|9|255 ');
	}

	T_Str = copy( Caps( Get_Word('|9|255 ') ),1,4);  /* Get the current word */

	if(  (T_Str == 'ELSE') | (T_Str == 'IF')  ) {
		Str1 = 'IF';
		Xtr2 = 'ENDIF';
		Str2 = 'ENDI';
		S_Str = '{%[|9 ]*IF}||{%[|9 ]*ENDI}';
		GOTO Match_Down;
	}

	if(  T_Str == 'ENDI'  ) {
		Str1 = 'ENDI';
		Xtr2 = 'IF';
		Str2 = 'IF';
		S_Str = '{%[|9 ]*IF}||{%[|9 ]*ENDI}';
		GOTO Match_Up;
	}

	if(  (T_Str == 'TEXT')  ) {
		Str1 = 'TEXT';
		Xtr2 = 'ENDTEXT';
		Str2 = 'ENDT';
		S_Str = '{%[|9 ]*TEXT}||{%[|9 ]*ENDT}';
		GOTO Match_Down;
	}

	if(  T_Str == 'ENDT'  ) {
		Str1 = 'ENDT';
		Xtr2 = 'TEXT';
		Str2 = 'TEXT';
		S_Str = '{%[|9 ]*TEXT}||{%[|9 ]*ENDT}';
		GOTO Match_Up;
	}

	if(  T_Str == 'DO'  ) {
		Word_Right;
		T_Str = copy( Caps( Get_Word(' ') ),1,4);  /* Get the current word */
	}

	/*  check for either a DO WHILE or a simple WHILE or LOOP or EXIT  */
	if(  (T_Str == 'WHIL') | (T_Str == 'EXIT') | (T_Str == 'LOOP')  ) {
		Str1 = 'DO WHIL';
		Xtr2 = 'ENDDO';
		Str2 = 'ENDD';
		S_Str = '{%[|9 ]*DO[|9 ]+WHIL}||{%[|9 ]*ENDD}';
		GOTO Match_Down;
	}

	/*  check for either a DO CASE or  simple CASE or OTHERWISE  */
	if(  (T_Str == 'CASE') | (T_str == 'OTHE')  ) {
		Str1 = 'DO CASE';
		Xtr2 = 'ENDCASE';
		Str2 = 'ENDC';
		S_Str = '{%[|9 ]*DO[|9 ]+CASE}||{%[|9 ]*ENDC}';
		GOTO Match_Down;
	}

	if(  T_Str == 'ENDD'  ) {
		Str1 = 'ENDD';
		Xtr2 = 'DO WHILE';
		Str2 = 'DO WHIL';
		S_Str = '{%[|9 ]*DO[|9 ]+WHIL}||{%[|9 ]*ENDD}';
		GOTO Match_Up;
	}

	if(  T_Str == 'ENDC'  ) {
		Str1 = 'ENDC';
		Xtr2 = 'DO CASE';
		Str2 = 'DO CASE';
			S_Str = '{%[|9 ]*DO[|9 ]+CASE}||{%[|9 ]*ENDC}';
		GOTO Match_Up;
	}

	Make_Message('Looking for the Next Control Word');
	GOTO_MARK;
	S_Str = '{%[|9 ]*IF}||{%[|9 ]*ENDI}||{%[|9 ]*DO[|9 ]+WHIL}||{%[|9 ]*DO[|9 ]+CASE}||{%[|9 ]*ENDD}||{%[|9 ]*ENDC}||{%[|9 ]*TEXT}||{%[|9 ]*ENDT}';
	S_Res = Search_Fwd(S_Str,0);
	if(  (S_res == true)  ) {
		Make_Message('Next Control Word');
	} else {
		Make_message('no control word found');
	}
	GOTO Macro_Exit;

Match_Up:
	Direction = 0;
	goto_col(1);
	GOTO Start_Match;

Match_Down:
	Direction = 1;

Start_Match:
	Reg_Exp_Stat = True;
	Ignore_Case = True;
	B_Count = 1;
	S_Res = 1;
	Make_Message('Matching...  Press <ESC> to Stop.');
	Working;

MATCH_LOOP:   /* Main loop */

					/* If the <ESC> key is pressed while matching then abort the search */
	if(  check_key  ) {
		if(  key1 == 27  ) {
			GOTO_MARK;
			Make_Message('Match Aborted.');
			goto macro_exit;
		}
	}

	if(  B_Count == 0  ) { /* If match count is 0 then success */
		GOTO Found_Exit;
	}

	if(  Direction == 1  ) { /* Perform search based on direction */
		Right;
		S_Res = Search_Fwd(S_Str,0);
	} else {
		Left;
		S_Res = Search_Bwd(S_Str,0);
	}

	if(  S_Res == 0  ) {   /* If search failed then exit */
		GOTO Error_Exit;
	}

	FStr = Found_Str;
	tabs_to_spaces( fstr );
	fstr = Caps(remove_space( fstr ));

											 /* Get the found string and capitalize it */
												/* If we found the first match string then */
	if(  FStr == STR1  ) {
		B_Count = B_Count + 1;   /* Inc the match count */
	} else {
		if(  FStr == STR2  ) {          /* If we found the second match string then */
			B_Count = B_Count - 1;    /*   decrement the match count */
		}                         /* ignore everything else */
	}

	GOTO Match_Loop;


Error_Exit:     /* Go here for unsucessfull match */
	GOTO_MARK;
	Make_Message('Did Not Find '+Xtr2);
	GOTO Macro_Exit;

Found_Exit:     /* Go here for successfull match */
	POP_MARK;
	Make_Message('Found '+Xtr2);

Macro_Exit:
	ignore_case = temp_case;
	Refresh = True;
	Redraw;
}
/*  */
macro DBA_IND {
/*******************************************************************************
																MULTI-EDIT MACRO

Name: DBA_IND

Description:  This macro will perform a smart indent when the <ENTER> key is
	pressed.  This macro is called by the macro CR.

							 (C) Copyright 1991 by American Cybernetics, Inc.
												Contributed by Terry Lovegrove
*******************************************************************************/

	str C_STR,S_STR,U_STR;          /* Word to check for indent */
	int T_COL,T_COL2;   /* Temp column positions */
	int sig_char_found,ind_count,jx;
	char found_char;

	MARK_POS;
	Reg_Exp_Stat = True;
	Refresh = False;
	LEFT;
	/* Check to see if we are inside a comment */
	/* Don't go back farther than 20 lines in order to improve speed */
	if(  Search_Bwd('@{||@}||{(@*}||{@*)}',20)  ) {
		if(  (Cur_Char == '{') | (Cur_Char == '(')  ) {
			if(  (Cur_Char == '{')  ) {
				RIGHT;
			} else {
				RIGHT;
				RIGHT;
			}
			Set_Indent_Level;
			GOTO_MARK;
			Refresh = True;
			CR;
			GOTO MAC_EXIT;
		}
	}

	GOTO_MARK;
	MARK_POS;

	CALL SKIP_CLIP_NOISE1;
	FOUND_CHAR = CUR_CHAR;
	GOTO_MARK;
	REFRESH = TRUE;

	T_COL2 = C_COL;         /* Store current position */
	FIRST_WORD;              /* Go to the first word on the line */
	T_COL = C_COL;          /* Store this position */

	if(  T_COL2 < T_COL  ) {   /* If this position is greater than the original */
		T_COL = T_COL2;       /*   then store the original */
		GOTO_COL(T_COL);       /*   and go there */
	}
	if(  Cur_Char != '|0'  ) { /* If we are beyond the end of the line then */
		SET_INDENT_LEVEL;      /*   set the indent level */
	}

	T_COL = C_COL;          /* Store the current position */
													 /* Get the current word, removing any extra space */
	C_STR = ' ' + REMOVE_SPACE(CAPS( GET_WORD('; (,{') )) + ' ';
	if(  XPOS(C_STR,' PROCEDURE FUNCTION DO CASE NEXT OTHERWISE IF FOR ',1) &
		XPOS(' END',C_STR,1) &
		XPOS(' ELSE',C_STR,1)  ) {
		GOTO MAC_EXIT;
	}
	Right;
	S_STR = ' ' + REMOVE_SPACE(CAPS( GET_WORD('; (,{') )) + ' ';
	GOTO_COL(T_COL2);        /* Put cursor on original position */
	CR;                      /* Perform a carriage return */

													 /* If word in this list and not just after */
													 /*  a DO CASE then pull out the word */
	if(  (XPOS(' END',C_STR,1) != 0) |
		(XPOS(' ELSE',C_STR,1) != 0) |
		(XPOS(C_STR,' NEXT OTHERWISE ',1)!= 0)  ) {
			CALL OUTDENT;
			if(  C_STR == ' ENDCASE '  ) {
				CALL OUTDENT;
			}
	} else {
			if(  (C_STR == ' CASE ')  ) {
				Mark_Pos;
				Up;
				Up;
				First_Word;
				U_STR = ' ' + REMOVE_SPACE(CAPS( GET_WORD('; (,{') )) + ' ';
				Right;
				U_STR = U_STR + REMOVE_SPACE(CAPS( GET_WORD('; (,{') )) + ' ';
				Goto_Mark;
				if(  (U_STR != ' DO CASE ')  ) {
					CALL OUTDENT;
				}
			}
	}
														/* If DO CASE or DO WHILE indent */
	if(  (C_STR == ' DO ') & (XPOS(S_STR,' CASE WHILE ',1)!= 0)  ) {
		INDENT;
	}

													 /* If the word is in this list indent */
	if(  (T_COL != T_COL2) & (LENGTH(C_STR) != 0) &
		((XPOS(C_STR,' PROCEDURE FUNCTION FOR CASE OTHERWISE IF ',1)!= 0)
		| (XPOS(' ELSE',C_STR,1) != 0))  ) {
			INDENT;
	}
	GOTO MAC_EXIT;

OUTDENT:
				UNDENT;
				T_Col = C_Col;
				UP;
				MARK_POS;
				FIRST_WORD;
				T_Col = C_Col - T_Col;
				GOTO_MARK;
				if(  T_Col > 0  ) { DEL_CHARS(T_Col); }
				DOWN;
				RET;

SKIP_CLIP_NOISE1:

/*  Here we look for the nearest preceding nonblank character.  If it is a
	closing comment then we find the  nearest opening comment.
	 */

	if(  (SEARCH_BWD('[~ ]', 1))  ) {
		if(  (CUR_CHAR == ')')  ) {
			LEFT;
			if(  (CUR_CHAR == '*')  ) {
				JX = SEARCH_BWD('(@*', 0);
				LEFT;
				GOTO SKIP_CLIP_NOISE1;
			}
			RIGHT;
			SIG_CHAR_FOUND = TRUE;
			GOTO EXIT_SKIP_CLIP;
		} else {
			if(  (CUR_CHAR == '}')  ) {
				JX = SEARCH_BWD('@{', 0);
				LEFT;
				GOTO SKIP_CLIP_NOISE1;
			}
		}

		SIG_CHAR_FOUND = TRUE;
		GOTO EXIT_SKIP_CLIP;
	}

/*  If we failed to find a nonblank character on the current line, and the
	cursor is on line 1, we failed to find a significant character; otherwise,
	we back up a line and try again.  */

	if(  (C_LINE == 1)  ) {
		SIG_CHAR_FOUND = FALSE;
		GOTO EXIT_SKIP_CLIP;
	}
	UP;
	EOL;
	GOTO SKIP_CLIP_NOISE1;

EXIT_SKIP_CLIP:
	REFRESH = TRUE;
	RET;



MAC_EXIT:

}