// $Header: /MeWin/Src/LANGUAGE.S 10    4/23/96 16:37 Dan $

macro_file LANGUAGE;

#include METOOLS.SH
#include LANGUAGE.SH
#include DBTOOLS.SH
#include WINDOWS.SH
#include DB.SH

#ifdef _Debug_
	#include MSGLOG.SH
#endif

int LangGetRecord( str &Language, str &Record )
/******************************************************************************
															 Multi-Edit Macro
															 19-Oct-95  22:29

	Function: Get the language config record for Language.

	Entry   : str Language	- The language to get the config data for.  If ""
														then use the file name specified in Record or the
														current file name to determine the language.

						str Record		- A variable used to return the record data.  When
														Language is "" Record can contain a file name to
														use to determine the language or "" to use current
														file name.

	Exit    : int
							_NoError					- Record found.
								Language					- The selected language name.
								Record						- The config data for Language.

							_ErrorNoDbRecord	- Error no record found.
								Language					- The selected language or "".
								Record						- "".

							 Copyright (C) 1995 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
	int Result = _ErrorNoDbRecord;
	int RecNum = 0;
	int Flags = _sf_FirstField | _sf_ErrorNoRec | _dbf_NoDelWin;

	if ( Svl( Language ) == 0 ) {
		if ( Svl( Record ) == 0 ) {
			Record = File_Name;
		}
		Language = Parse_Str( "\x7F" + "LS=",
			Global_Str( "." + Get_Extension( Record ) ) );
	}
	if ( Svl( Language ) ) {
		Result = _NoError;
		Record = Global_Str( _LangRecGlob + Language );
		if ( Svl( Record ) == 0 ) {
			Record = Language;
			Result = DbGetRecord( "MECONFIG", _db_lang_Page, _db_lang_Type, Record,
					RecNum, Flags, "" );
			if ( Result == _NoError ) {
				Set_Global_Str( _LangRecGlob + Language, Record );
			}
		}
	}
	if ( Result != _NoError ) {
		Record = "";
	}
	return ( Result );

}  // LangGetRec

void LangSetProperties(
			int Dlg 	 = Parse_Int( "/DLGHANDLE=", MParm_Str ),
			int CtrlId = Parse_Int( "/CID=", MParm_Str ),
			str Misc	 = MParm_Str
)
/******************************************************************************
															 Multi-Edit Macro
															 16-Aug-95  16:33

  Function: Run the specified Config macro for a selected language to set
 						additional language properties.  This should only run by the
						Language Setup dialog.

  Entry   : int Dlg				- The dialog window handle ( Windows ) (/DLGHANDLE=)
 						int CtrlId		-	The control id of the config macro string (/CID=)
						str Misc			- Misc parameters passed to the Properties macro

  Exit    : None

							 Copyright (C) 1995 by American Cybernectic, Inc.
********************************************************************( ldh )***/
{
	str TStr;

	Error_Level = 1;
	if ( Dlg && CtrlId ) {
  	GetDlgItemText( Dlg, CtrlId, TStr, 254 );
		if ( Svl( TStr ) ) {
			// Run language config macro
			if ( XPos( " ", TStr, 1 ) == 0 ) {
				TStr += " ";
			}
			Error_Level = 0;
			Rm( TStr + Misc );
			if ( Error_Level ) {
				Rm( "MeError" );
			}
		}
	}
	if ( Error_Level ) {
		Make_Message( "No properties for this language." );
		Error_Level = 0;
	}

}  // LangSetProperties

int LangDoMatch(
			str LangPrefix = Parse_Str( "/LP=", MParm_Str ),
			str MatchStr	 = Parse_Str( "/MS=", MParm_Str ),
			str ParmStr		 = MParm_Str
) trans
/******************************************************************************
															 Multi-Edit Macro
															 04-Apr-96  09:55

  Function: Find matching language constructs.

	Entry   : str LangPrefix	- The first three character of the language 	(/LP=)
						str MatchStr		- The string to match, if "" then find string (/MS=)
						str ParmStr			- Additional parameters
              /HI=1           - Highlight matched text
              /BL=1           - Mark the text as a block
							/RC=1    				-	Restore cursor to original position
							/LS=x    				-	Limit scope of search to x number of lines
							/NM=1						- Display no messages
							/NA=1						- No check for abort
							/IC=1						- Starting match in comment
  															(Only used when MatchStr is passed)

	Exit    : Return_Int
						 -1					- Search aborted
							0         - Match found
							1         - No match found

	Author	: Dan Hughes

							 Copyright (C) 1996 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
  int ShowMessage = !Parse_Int( "/NM=", ParmStr );
  int EnableAbort = !Parse_Int( "/NA=", ParmStr );
  int Scope       = Parse_Int( "/LS=", ParmStr );

	int FndWord 		= False;
	int Second_Time = False;
	int SavRefresh	= Refresh;

	int T_Line = C_Line;
	int T_Col  = C_Col;
	int F_Line;
	int F_Col;
	int T_Row;
	int Jx;
	int Jy;

	int StartInCmt;
	int Direction;   /* 0 = search forward, _Backward = backward */
	int B_Count;     /* Match count.  0 = match found */
	int S_Res;       /* Search results */

  str GStr                      = "!" + LangPrefix + "Match";
  str BegPat[ Max_Line_Length ] = Global_Str( GStr + "BegPat" );
  str EndPat[ Max_Line_Length ] = Global_Str( GStr + "EndPat" );
  str BChars;
  str EChars;
  str LangMac;
	str SkipBChars;

  str Str1;     /* Match strings */
	str MStr1;
	str EStr1;
	str S_Str;
	str TStr;
	str FStr;
	str Msg;

  TStr = Global_Str( GStr + "Extra" );
  BChars = Parse_Str( _mtchBChars, TStr );
  EChars = Parse_Str( _mtchEChars, TStr );
  LangMac = "_" + LangPrefix + "GetMatchPat " + TStr;

//	Refresh = True;
	Refresh = False;
	Push_Undo;
	Mark_Pos;

	if ( Svl( MatchStr ) != 0 ) {
		TStr = "\x7F" + MatchStr + "\x7F";
		if ( XPos( "/IC=", ParmStr, 1 ) ) {
			StartInCmt = Parse_Int( "/IC=", ParmStr );
		}
		else {
			StartInCmt = GetStatusAtCursor( );
		}
		Mark_Pos;
	}
	else {
		TStr = '';
	}

Find_Match_Str:
	FndWord = False;
	SkipBChars = " \t\xFF";
	if ( Svl( TStr ) == 0 ) {
  	// Run language specific GetMatchPat macro
  	Rm( LangMac );
  	TStr = Return_Str;
  	StartInCmt = g_LangInCmt;
	}
	if ( Svl( TStr ) == 0 ) {
		if ( At_Eol  ) { /* If we are at the end of a line then go to the first word */
			First_Word;
		}
		while ( XPos( Cur_Char, " \t\xFF", 1 ) && !At_Eol ) {
			Right;
		}
		Mark_Pos;
		// Get the current word
		TStr = "\x7F" + Caps( Get_Word( EChars ) ) + "\x7F";
		FndWord = True;
		SkipBChars = BChars;
	}
//DebugLog( 1, "LangDoMatch", "|%s|", TStr );

	// Setup the search parameters
	if ( Jx = XPos( TStr, BegPat, 1 ) ) {
		// Search forward
		Direction = 0;
		Jx = XPos( _mtchBeg, BegPat, Jx );
		Jy = XPos( _mtchMid, BegPat, Jx + 1 );
		// Get begin patterns
		Str1 = Copy( BegPat, Jx + 3, Jy - Jx - 3 );
		Jx = XPos( _mtchEnd, BegPat, Jy + 1 );
		// Get middle patterns
		MStr1 = Copy( BegPat, Jy +3, Jx - Jy - 3 );
		Jy = XPos( _mtchExp, BegPat, Jx + 1 );
		// Get end patterns
		EStr1 = Copy( BegPat, Jx + 3, Jy - Jx - 3);
		Jx = XPos( "\x7F", BegPat, Jy + 1 );
		// Get search expression
		S_Str = Copy( BegPat, Jy + 3, Jx - Jy - 3 );
		if ( FndWord ) {
			S_Str = "(^|[" + Make_Literal_X( BChars ) + "]" + S_Str + "$|[" +
					Make_Literal_X( EChars ) + "])";
		}
	}
	else if ( Jx = XPos( TStr, EndPat, 1 ) ) {
		// Search backward
		Direction = _Backward;
		MStr1 = '';
		Jx = XPos( _mtchBeg, EndPat, Jx );
		Jy = XPos( _mtchEnd, EndPat, Jx + 1 );
		// Get begin patterns
		Str1 = Copy( EndPat, Jx + 3, Jy - Jx - 3 );
		Jx = XPos( _mtchExp, EndPat, Jy + 1 );
		// Get end patterns
		EStr1 = Copy( EndPat, Jy + 3, Jx - Jy - 3);
		Jy = XPos( "\x7F", EndPat, Jx + 1 );
		// Get search expression
		S_Str = Copy( EndPat, Jx + 3, Jy - Jx - 3 );
		if ( FndWord ) {
			S_Str = "(^|[" + Make_Literal_X( BChars ) + "]" + S_Str + "$|[" +
					Make_Literal_X( EChars ) + "])";
			Pop_Mark;
			Left;
			Mark_Pos;
			Word_Left;
			Left;
		}
	}
	else {
		// If we didn't find a word to match the first time then try again
		if ( !Second_Time ) {
			Pop_Mark;
			Second_Time = True;
			First_Word;
			TStr = '';
			goto Find_Match_Str;
		}
		Pop_Mark;
		Goto_Mark;
		Msg = "Nothing to match.";
		goto Macro_Exit;
	}
//DebugLog( 1, "LangDoMatch", "|%s|%s|%s|%s|%s", TStr, Str1, MStr1, EStr1, S_Str );

	// Start search
	B_Count = 1;
	S_Res = 1;
	if ( ShowMessage ) {
		Msg = "Matching \"" + Copy( TStr, 2, Svl( TStr ) - 2 ) + "\"...";
		if ( EnableAbort ) {
			Msg += "  Press <ESC> to Abort.";
		}
		Make_Message( Msg );
	}
	Working;
	while ( S_Res && B_Count ) {
		if ( EnableAbort ) {
			if ( Check_Key ) {
				if ( ( Key1 == 27 ) && ( Key2 == 1 ) ) {
					// the <ESC> key pressed, abort the search
					Pop_Mark;
					Goto_Mark;
					Return_Int = -1;
					Msg = "Match aborted.";
					break;
				}
			}
		}
		if ( Direction == 0 ) { // Perform search based on direction
			if ( Scope > 0 ) {
				if ( C_Line > ( T_Line + Scope ) ) {
					S_Res = 0;
					break;
				}
			}
			Right;
			while ( !At_Eol && XPos( Cur_Char, SkipBChars, 1 ) ) {
				Right;
			}
		}
		else {
			if ( Scope > 0 ) {
				if ( C_Line < ( T_Line - Scope ) ) {
					S_Res = 0;
					break;
				}
			}
			Left;
			while ( ( ( C_Line > 1 ) || ( C_Col > 1 ) ) &&
					XPos( Cur_Char, SkipBChars, 1 ) ) {
				Left;
			}
		}
		S_Res = Find_Text( S_Str, 0, _RegExp | Direction );
		if ( S_Res == 0 ) {                   // If search failed then exit
			break;
		}
		if ( GetStatusAtCursor( ) && !StartInCmt ) {
			continue;
		}
		FStr = Caps( Found_Str );
//DebugLog( 1, "LangDoMatch", "|%s|", FStr );
		if ( Svl( FStr ) > 2 ) {
			// If the first char is a space or a ;
			if ( XPos( Copy( FStr, 1, 1 ), BChars, 1 ) ) {
				FStr = Copy( FStr, 2, 20 );     // then eliminate it
				while ( !At_Eol && XPos( Cur_Char, BChars, 1 ) ) {
					Right;
				}
			}
			// If it ended in a space, ; or . then
			if ( XPos( Copy( FStr, Length( FStr ), 1 ), EChars, 1 ) ) {
				FStr = Copy( FStr, 1, Length( FStr ) - 1 );  // eliminate that char
			}
		}
		if ( XPos( " " + FStr + " ", Str1, 1 ) ) {
			// found the first match string so, increment the match count
			++B_Count;
		}
		else if ( XPos( " " + FStr + " ", EStr1, 1 ) ) {
			// found the second match string, decrement the match count
			--B_Count;
		}
		else if ( XPos( " " + FStr + " ", MStr1, 1 ) ) {
			if ( B_Count == 1 ) {
				--B_Count;
			}
		}
	}  // while

	if ( S_Res == 0 ) {                   // Unsuccessful match
		Pop_Mark;
		Goto_Mark;
		if ( Scope > 0 ) {
			Msg = "No match within " + Str( Scope ) + " lines.";
		}
		else {
			Msg = "No match found.";
		}
		Return_Int = 1;
	}
	else if ( B_Count == 0 ) {            // Successful match
		F_Line = C_Line;
		F_Col = C_Col;

		if ( C_Line > T_Line ) {
			Jx = C_Line - T_Line;
		}
		else {
			Jx = T_Line - C_Line;
		}

		Goto_Mark;
		Mark_Pos;
		T_Col = C_Col;
		T_Line = C_Line;

    int Highlight_Block = Parse_Int( "/HI=", ParmStr );
    if(parse_int("/BL=", ParmStr))
    {
      Highlight_Block = 2;
    }

		if ( Jx < Win_CHeight ) {
			while ( Jx > 0 ) {
				--Jx;
				if ( F_Line > T_Line ) {
					Down;
				}
				else {
					Up;
				}
			}
		}
		else {
      if(Highlight_Block == 1)
        Highlight_Block = False;
		}
    if ( Parse_Int( "/RC=", ParmStr ) ) {
			// Return to starting position
			Goto_Mark;
		}
		else {
			Pop_Mark;
			Goto_Line( F_Line );
			Goto_Col( F_Col );
		}
		// Remove original position marker
		Pop_Mark;
		if ( Highlight_Block ) {
			if ( F_Line > T_Line ) {
				F_Col += Svl( FStr );
			}
			else if ( T_Line > F_Line ) {
				++T_Col;
			}
			else {
				if ( F_Col > T_Col ) {
					F_Col += Svl( FStr );
				}
				else {
					++T_Col;
				}
			}
      if(Highlight_Block == 2)
      {
        if(f_line == t_line)
        {
          if(f_col > t_col)
          {
            jx = t_col;
            t_col = f_col;
            f_col = jx;
          }
        }
        if(f_line > t_line)
        {
          jx = t_col;
          t_col = f_col;
          f_col = jx;

          jx = t_line;
          t_line = f_line;
          f_line = jx;
        }
        Block_line1 = F_Line;
        Block_Line2 = T_Line;
        Block_Col1 = F_Col;
        Block_Col2 = T_Col - 1;
        Block_Stat = 3;
      }
      else
      {
        Set_Highlight( F_Line, F_Col, T_Line, T_Col );
      }
		}
		Msg = "Match found.";
		Return_Int = 0;
	}

Macro_Exit:
	if ( ShowMessage ) {
		Make_Message( Msg );
	}
	Refresh = SavRefresh;
	Pop_Undo;
	Redraw;
  g_LangInCmt = 0;
  return ( Return_Int );

}  // LangDoMatch

void LangCloseParen(
			str LangPrefix = Parse_Str( "/LP=", MParm_Str ),
			str ParmStr 	 = MParm_Str
)
/******************************************************************************
															 Multi-Edit Macro
															 09-Apr-96  13:59

	Function: Auto match the opening paren for the specified language.

	Entry   : str LangPrefix	- The first three letters of the language (/LP=)
						str ParmStr			- Additional parameters ( See LangDoMatch )

	Exit    : None
	Author  : Dan Hughes

							 Copyright (C) 1996 by American Cybernetics, Inc.
********************************************************************( ldh )***/
{
	int SavRefresh = Refresh;
	int TSearch_Highlight;

  Push_Undo;
	Refresh = False;
  Text( ")" );
	if ( ( ( GetStatusAtCursor( ) & 0x0F ) == 0 ) && Svl( LangPrefix ) ) {
  	Left;
  	LangDoMatch( LangPrefix, ")", ParmStr + "/RC=1/HI=1/LS=20" );
		TSearch_Highlight = Search_Highlight;
		Right;
		Search_Highlight = TSearch_Highlight;
	}
	Refresh = SavRefresh;
  Pop_Undo;

}  // LangCloseParen

int Match( ) trans2
/******************************************************************************
																MULTI_EDIT MACRO

	Function: Calls the matching macro defined for the language specified by
						the filename extension of the current file.  If no macro is defined,
						the macro name is determined by the first three characters of the
						language type followed by 'MTCH'. For example, the pascal matching
						macro would be named 'PASMTCH', the C macro would be 'CMTCH'

							 (C) Copyright 1992 by American Cybernetics, Inc.
******************************************************************************/
{
	str TStr;
	str Language;
	str LanguageRec[ Max_Line_Length ];

	Error_Level = 1;
	if ( LangGetRecord( Language, LanguageRec ) == _NoError ) {
		TStr = Parse_Str( "\x7F" + _db_lang_MatchMac + "=", LanguageRec );
	}
  return_int = 0;
	if ( Svl( TStr ) == 0 ) {
		if ( Svl( Language ) != 0 ) {
			TStr = Copy( Language, 1, 8 ) + "^" + Copy( Language, 1, 3 ) +
          "Mtch " + mparm_str + "/HI=1";
		}
	}
	if ( Svl( TStr ) != 0 ) {
		Error_Level = 0;
    Rm( TStr + " " + mparm_str );
	}
	if ( Error_Level != 0 ) {
		Make_Message( "NOT Supported for this file extension." );
		Error_Level = 0;
	}
  return(return_int);
}  // Match

void Lang_Menu( ) trans2
/*******************************************************************************
															 MULTI-EDIT MACRO

Name:  LANG_MENU

Description:  Menu of language types for extension setup

							 (C) Copyright 1991 by American Cybernetics, Inc.
*******************************************************************************/
{
// GET_DB_RECORD stores the initial amount of records in global_int("@LANG")
	str extraparms = "";

	int active_window = window_id;
	int list_mode = parse_int("/LM=", mparm_str);
	if(parse_int("/CE=",mparm_str))
	{
		extraparms = "/NL=1" + "/FV=" + parse_str("LS=", Global_Str("." + get_extension(file_name)));
	}

	if(!xpos("/LM=",mparm_str, 1)) {
		list_mode = 2;
	}
	mark_pos;
	RM("GET_DB_RECORD /NDF=1/F=MECONFIG/DPT=LANGUAGE.DB/DBF=LANG/AGLO=@LANG/#=1");
	switch_win_id(active_window);
	goto_mark;
	Db( "MECONFIG", "LANGUAGE.DB", "MEWHDRS.DB", "LANGUAGE.HDR",
			"Languages", "Language Setup", "@LANG", list_mode,
			extraparms + "/NDH=1/PRE=LANG/H=" + LANGUAGES_HELPLINK + "/BMP=BT_SETUP_108/FV=" +
					parse_str("/STR=", mparm_str) + "/MACRO=LANG_WARNING"
			);
	set_global_int("@LANG",0);
	// Clear language record global
	Set_Global_Str( _LangRecGlob + Parse_Str( "\x7F" + "LANG=", Global_Str( "@Lang" ) ),
			"" );
}

void Lang_Warning trans2
/*******************************************************************************
															 MULTI-EDIT MACRO

Name:  LANG_WARNING

Description:  Warns user that he cannot just arbitrarily add language types
							without having support for them.  Also handles the
							reinitializing of syntax highlighting parameters on the fly.

							 (C) Copyright 1991 by American Cybernetics, Inc.
*******************************************************************************/
{
	str language[40];
	int active_window = window_id;
	mark_pos;

	if(  (Parse_Int('/P=',MParm_Str))  ) {
		language = parse_str("LANG=",global_str("@LANG"));
		if (length(global_str("@LANG")) >
			(svl(language) + 6)) {
			set_global_str("@" + copy(language,1,3) + "_SYNTAX_PARMS",global_str("@LANG"));
			// this will reinit the syntax highliting for this language
			RM("SET_SYNTAX_PARMS /LANG=" + language);
		}
		if (parse_int("/NOCHECK=",mparm_str) == 0) {
			//check record count against orignal amount
			Mark_Pos;
			RM("GET_DB_RECORD /NDF=1/F=MECONFIG/DPT=LANGUAGE.DB/DBF=LANG/AGLO=@TLANG/FV=" + language);
			Goto_Mark;
			if (global_int("@TLANG") > global_int("@LANG") ) {
				RM('MEERROR^MessageBox /T=WARNING/B=1/M=If you added any new language types, be sure that you have the appropriate support macros.');
			}
			set_global_int("@TLANG",0);
		}
	}
	switch_win_id(active_window);
	goto_mark;
}

#ifdef Windows
void _CommentCode( struct tCommentChars rCC )
/******************** Multi-Edit VOID Macro Function ************************

 NAME:        _CommentCode               *INTERNAL*

 DESCRIPTION: Translates current block mark into a comment block
							If block_stat = 0,  current line using open,close comment string
															1,  current line using eol comment string
															2,  remainder of current line using eol string
															3,  start,end block mark with comment chars

 PARAMETERS:  None

 RETURNS:     (void)

 COMMENTS:

 NOTES:       NOTES: Beware of creating nested comments.  Most languages
							do not support them.


*****************************10-06-94 01:53pm*******************************/
{
	int TRefresh 					 = Refresh;
	int TInsert_Mode 			 = Insert_Mode;
	int TPersistent_Blocks = Persistent_Blocks;
	int KeepMarking				 = g_KeepBlkMarking;
	int BLin1 						 = Block_Line1;
	int BLin2 						 = Block_Line2;
	int BCol1 						 = Block_Col1;
	int BCol2 						 = Block_Col2;
	int SavBlk					   = 0;
	int Jx;
	int Jy;

	str TStr[ Max_Line_Length ];

	Push_Undo;
	Mark_Pos;

	Refresh = False;
	Persistent_Blocks = True;

	// Check if cursor in a block
	if ( CursorInBlock( True ) == False ) {
		// Push block on stack and hide if block marked
	 	SavBlk = PushBlock( True );
	}
	switch ( Block_Stat ) {
		case _StrBlock :										// stream mark - open and close
			Insert_Mode = True;
			if ( rCC.szOpenComment1 == '' ) {
				for ( Jx = BLin1; Jx <= BLin2; ++Jx ) {
					Goto_Line( Jx );
					if ( Jx == BLin1 ) {
						Goto_Col( BCol1 );
					}
					else if ( ( BCol2 == 0 ) && ( BLin2 == Jx ) ) {
						break;
					}
					else {
						Goto_Col( 1 );
					}
					if ( Shorten_Str( Get_Line( ) ) != '' ) {
						Text( rCC.szEOLComment1 );
					}
				}
			}
			else {
				Goto_Line( BLin2 );
				Goto_Col( BCol2 + 1 );
				Text( rCC.szCloseComment1 );
				Block_Col2 = C_Col - 1;

				Goto_Line( BLin1 );
				Goto_Col( BCol1 );
				Text( rCC.szOpenComment1 );
				Block_Col1 = BCol1;
			}
			break;

		case _ColBlock :										// column mark - use eol if available
																				//               else use open,close
			Insert_Mode = False;
			for ( Jx = Block_Line1; Jx <= BLin2; ++Jx ) {
				Goto_Line( Jx );
				Goto_Col( BCol1 );
				TStr = Get_Line( );
				if ( Shorten_Str( TStr ) != '' ) {
					if ( rCC.szEOLComment1 != '' ) {
						Insert_Mode = True;
						Text( rCC.szEOLComment1 );
					}
					else {
						TStr = Copy( TStr, BCol1, Svl( TStr ) - BCol1 + 1 );
						Text( rCC.szOpenComment1 + TStr + rCC.szCloseComment1 );
					}
				}
			}
			Insert_Mode = True;
			break;

		case _LinBlock :					 	// line mark     - try eol, else open,close
			Insert_Mode = True;
			for ( Jx = Block_Line1; Jx <= BLin2; ++Jx ) {
				Goto_Line( Jx );
				Goto_Col( 1 );
				TStr = Get_Line( );
				if ( Shorten_Str( TStr ) != '' ) {
					if ( rCC.szEOLComment1 != '' ) {
						Text( rCC.szEOLComment1 );
					}
					else {
						Insert_Mode = False; // overwrite
						if ( Jy = XPos( rCC.szOpenComment1, TStr, 1 ) ) {
							TStr = Str_Ins( rCC.szCloseComment1, TStr, Jy );
							Text( rCC.szOpenComment1 + TStr );
						}
						else {
							Text( rCC.szOpenComment1 + TStr + rCC.szCloseComment1 );
						}
						Insert_Mode = True;
					}
				}
			}
			break;

		case 0 :                  // no block mark - open and close line
		default:
			TStr = Get_Line( );
			Goto_Col( 1 );
			if ( Shorten_Str( TStr ) != '' ) {
				if ( rCC.szEOLComment1 != '' ) {
					Insert_Mode = True;
					Text( rCC.szEOLComment1 );
				}
				else {
					Insert_Mode = False; // overwrite
					if ( Jx = XPos( rCC.szOpenComment1, TStr, 1 ) ) {
						TStr = Str_Ins( rCC.szCloseComment1, TStr, Jx );
						Text( rCC.szOpenComment1 + TStr );
					}
					else {
						Text( rCC.szOpenComment1 + TStr + rCC.szCloseComment1 );
					}
				}
			}
			break;
	}
	Insert_Mode = TInsert_Mode;
	Goto_Mark;
	if ( Block_Stat == 0 ) {
		Down;
	}
	// Pop block off stack and show if one pushed
	if ( SavBlk ) {
		PopBlock( True );
	}
	else if ( KeepMarking < 1 ) {
//		Block_Off;
		Block_End;
	}
	Pop_Undo;
	Redraw;
	Persistent_Blocks = TPersistent_Blocks;
	Refresh = TRefresh;

}  // _CommentCode

void _UncommentCode( struct tCommentChars rCC )
/******************** Multi-Edit VOID Macro Function ************************

 NAME:         _UncommentCode                *INTERNAL*

 DESCRIPTION:  Translates current block mark to uncommented code block

 PARAMETERS:   None

 RETURNS:      void

 COMMENTS:

 NOTES:       Beware of creating nested comments.  Most languages
							do not support them.

*****************************10-13-94 03:34pm*******************************/
{
	int sv_refresh 	= refresh;
	int sv_ins 			= insert_mode;
	int sv_pb 			= persistent_blocks;
	int KeepMarking	= g_KeepBlkMarking;
	int BLin1 			= Block_Line1;
	int BLin2 			= Block_Line2;
	int BCol1 			= Block_Col1;
	int BCol2 			= Block_Col2;
	int SavBlk 			= 0;
	int Jx;
	int Jy;

	str TStr[ Max_Line_Length ];

	char Search_Begin_Char = "^";
	str If_Begin_Char = "";

	int comment_column_start;

	str srchkey;
	str szFilExt;
	str szExtRef;

	str szLanguageRecord;

	Push_Undo;
	Mark_Pos;

	/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
	Refresh = False ;
	Persistent_Blocks = True;
	Comment_Column_Start = 0;

	// Check if cursor in a block
	if ( CursorInBlock( True ) == False ) {
		// Push block on stack and hide if block marked
	 	SavBlk = PushBlock( True );
	}
	switch ( Block_Stat ) {
		case _StrBlock :										// stream mark - open and close
			Insert_Mode = False;
			Goto_Line( BLin1 );
			Goto_Col( BCol1 );
			TStr = Get_Line( );
			if ( ( Jx = Length( rCC.szEOLComment1 ) ) != 0 ) {
				if ( Lower( Copy( TStr, BCol1, Jx ) ) == rCC.szEOLComment1 ) {
				}
			}
			if ( ( Jx = Length( rCC.szEOLComment2 ) ) != 0 ) {
				if ( Lower( Copy( TStr, BCol1, Jx ) ) == rCC.szEOLComment2 ) {
				}
			}
			if ( ( Jx = Length( rCC.szOpenComment1 ) ) != 0 ) {
				if ( Lower( Copy( Get_Line( ), BCol1, Jx ) ) == rCC.szOpenComment1 ) {
					Mark_Pos;
					Goto_Line( BLin2 );
					Goto_Col( BCol2 );
					Jy = Length( rCC.szCloseComment1 );
					if ( Lower( Copy( Get_Line( ), BCol2 - Jy + 1, Jy ) ) == rCC.szCloseComment1 ) {
						Goto_Col( BCol2 - Jy + 1 );
						Del_Chars( Jy );
						Block_Col2 = C_Col - 1;
						Goto_Mark;
						Del_Chars( Jx );
						break;
					}
					else {
						Pop_Mark;
					}
				}
			}
			if ( ( Jx = Length( rCC.szOpenComment2 ) ) != 0 ) {
				if ( Lower( Copy( Get_Line( ), BCol1, Jx ) ) == rCC.szOpenComment2 ) {
					Mark_Pos;
					Goto_Line( BLin2 );
					Goto_Col( BCol2 );
					Jy = Length( rCC.szCloseComment2 );
					if ( Lower( Copy( Get_Line( ), BCol2 - Jy + 1, Jy ) ) == rCC.szCloseComment2 ) {
						Goto_Col( BCol2 - Jy + 1 );
						Del_Chars( Jy );
						Block_Col2 = C_Col - 1;
						Goto_Mark;
						Del_Chars( Jx );
						break;
					}
					else {
						Pop_Mark;
					}
				}
			}
			break;

		case _ColBlock :										// column mark - use eol if available
																				//               else use open,close
			Insert_mode = False;
			for ( Jx = BLin1; Jx <= BLin2; ++Jx ) {
				Goto_Line( Jx );
				Goto_Col( BCol1 );
				TStr = Get_Line( );
				if ( Shorten_Str( TStr ) != '' ) {
					if ( ( Jy = Length( rCC.szEOLComment1 ) ) != 0 ) {
						if ( Lower( Copy( TStr, BCol1, Jy ) ) == rCC.szEOLComment1 ) {
							Del_Chars( Jy );
							continue;
//							goto column_removal_done;
						}
					}
					if ( ( Jy = Length( rCC.szEOLComment2 ) ) != 0 ) {
						if ( Lower( Copy( TStr, BCol1, Jy ) ) == rCC.szEOLComment2 ) {
							Del_Chars( Jy );
							continue;
//							goto column_removal_done;
						}
					}
					if ( ( Jy = Length( rCC.szOpenComment1 ) ) != 0 ) {
						if ( Lower( Copy( TStr, BCol1, Jy ) ) == rCC.szOpenComment1 ) {
							Goto_Line( Jx );
							Goto_Col( BCol1 );
							Comment_Column_Start = BCol1;
							call Uncomment_Line;
							continue;
//							goto column_removal_done;
						}
					}
					if ( ( Jy = Length( rCC.szOpenComment2 ) ) != 0 ) {
						if ( Lower( Copy( TStr, BCol1, Jy ) ) == rCC.szOpenComment2 ) {
							Goto_Line( Jx );
							Goto_Col( BCol1 );
							Comment_Column_Start = BCol1;
							call Uncomment_Line;
							continue;
//							goto column_removal_done;
						}
					}
				}
//column_removal_done:
			}
			Insert_Mode = True;
			break;

		case _LinBlock :										// line mark - try eol, else open,close
			Insert_mode = True;
			for ( Jx = BLin1; Jx <= BLin2; ++Jx ) {
				Goto_Line( Jx );
				call Uncomment_Line;
			}
			break;

		case 0 :                  // no block mark - uncomment current line
		default:
			call Uncomment_Line;
			break;
	}
	goto UC_Exit;


Uncomment_Line:
	if ( !Comment_Column_Start ) {
		Comment_Column_Start = 1;
		If_Begin_Char = Search_Begin_Char;
	}
	else {
		If_Begin_Char = "";
	}
	if ( rCC.szEOLComment1 != "" ) {
		if ( Shorten_Str( Get_Line( ) ) != "" ) {
			Goto_Col( Comment_Column_Start );
			SrchKey = "[ \t\xFF]*" + Make_Literal_X( rCC.szEOLComment1 );
			if ( Svl( If_Begin_Char ) ) {
				SrchKey = If_Begin_Char + SrchKey;
			}
			if ( Find_Text( SrchKey, 1, _RegExp ) ) {
				Forward_Till_Not( " \t\xFF" );
				Del_Chars( Length( rCC.szEOLComment1 ) );
				goto Line_Removal_Done;
			}
		}
	}
	else if ( rCC.szEOLComment2 != "" ) {
		if ( Shorten_Str( Get_Line( ) ) != "" ) {
			Goto_Col( Comment_Column_Start );
			SrchKey = "[ \t\xFF]*" + Make_Literal_X( rCC.szEOLComment2 );
			if ( Svl( If_Begin_Char ) ) {
				SrchKey = If_Begin_Char + SrchKey;
			}
			if ( Find_Text( SrchKey, 1, _RegExp ) ) {
				Forward_Till_Not( " \t\xFF" );
				Del_Chars( Length( rCC.szEOLComment2 ) );
				goto Line_Removal_Done;
			}
		}
	}
	else if ( rCC.szOpenComment1 != "" ) {
		if ( Shorten_Str( Get_Line( ) ) != "" ) {
			Goto_Col( Comment_Column_Start );
			SrchKey = "[ \t\xFF]*" + Make_Literal_X( rCC.szOpenComment1 );
			if ( Svl( If_Begin_Char ) ) {
				SrchKey = If_Begin_Char + SrchKey;
			}
			if ( Find_Text( SrchKey, 1, _RegExp ) ) {
				Push_Undo;
				Forward_Till_Not( " \t\xFF" );
				Del_Chars( Length( rCC.szOpenComment1 ) );
				Eol;
				Pop_Undo;
				SrchKey = Make_Literal_X( rCC.szCloseComment1 ) + "[ \t\xFF]*$";
				if ( Find_Text( SrchKey, 1, _RegExp | _Backward ) ) {
					Del_Chars( Length( rCC.szCloseComment1 ) );
					goto Line_Removal_Done;
				}
				else {
					Undo;
				}
			}
		}
	}
	if ( rCC.szOpenComment2 != "" ) {
		if ( shorten_str(get_line) != "" ) {
			goto_col(comment_column_start);
			srchkey = "[ \t\xFF]*" + Make_Literal_X( rCC.szOpenComment2 );
			if ( Svl( If_Begin_Char ) ) {
				SrchKey = If_Begin_Char + SrchKey;
			}
			if ( Find_Text( SrchKey, 1, _RegExp ) ) {
				Push_Undo;
				Forward_Till_Not( " \t\xFF" );
				Del_Chars( Length( rCC.szOpenComment2 ) );
				Eol;
				Pop_Undo;
				SrchKey = Make_Literal_X( rCC.szCloseComment2 ) + "[^ \t\xFF]*$";
				if ( Find_Text( SrchKey, 1, _RegExp | _Backward ) ) {
					Del_Chars( Length( rCC.szCloseComment2 ) );
					goto Line_Removal_Done;
				}
				else {
					Undo;
				}
			}
		}
	}

Line_Removal_Done:
	Comment_Column_Start = 0;
	ret;

UC_Exit:
	Insert_Mode = sv_ins;
	Goto_Mark;
	if ( Block_Stat == 0 ) {
		Down;
	}
	// Pop block off stack and show if one pushed
	if ( SavBlk ) {
		PopBlock( True );
	}
	else if ( KeepMarking < 1 ) {
//		Block_Off;
		Block_End;
	}
	Pop_Undo;
	Redraw;
	Persistent_Blocks = sv_PB;
	Refresh = sv_Refresh;
}  // _UncommentCode

void GetCommentChars( struct tCommentChars rCC )
/******************************************************************************
															 Multi-Edit Macro
															 29-Jun-95  12:04

  Function: Fill the tCommentChars rCC structure with the comment chars for the
						language specified by the current file.

  Entry   : struct tCommentChars rCC	- Structure to contain comment chars

							 Copyright (C) 1995 by American Cybernectic, Inc.
********************************************************************( ldh )***/
{
	str szLanguageType;
	str szLanguageRecord[ Max_Line_Length ];

	if ( LangGetRecord( szLanguageType, szLanguageRecord ) == _NoError ) {
		rCC.szOpenComment1  = Parse_Str( "\x7F" + _db_lang_OpenCmt1 + "=", szLanguageRecord );
		rCC.szCloseComment1 = Parse_Str( "\x7F" + _db_lang_CloseCmt1 + "=", szLanguageRecord );
		rCC.szEOLComment1   = Parse_Str( "\x7F" + _db_lang_EolCmt1 + "=", szLanguageRecord );

		rCC.szOpenComment2  = Parse_Str( "\x7F" + _db_lang_OpenCmt2 + "=", szLanguageRecord );
		rCC.szCloseComment2 = Parse_Str( "\x7F" + _db_lang_CloseCmt2 + "=", szLanguageRecord );
		rCC.szEOLComment2   = Parse_Str( "\x7F" + _db_lang_EolCmt2 + "=", szLanguageRecord );

		if ( rCC.szOpenComment1 == "" ) {
			rCC.szOpenComment1 = rCC.szOpenComment2;
		}
		if ( rCC.szCloseComment1 == "" ) {
			rCC.szCloseComment1 = rCC.szCloseComment2;
		}
		if ( rCC.szEOLComment1 == "" ) {
			rCC.szEOLComment1 = rCC.szEOLComment2;
		}
	}
	else {
		// die (do nothing, maybe a message)
		rCC.szOpenComment1  = "";
		rCC.szCloseComment1 = "";
		rCC.szEOLComment1   = "";

		rCC.szOpenComment2  = "";
		rCC.szCloseComment2 = "";
		rCC.szEOLComment2   = "";
	}
}  // GetCommentChars

void Comment( )
/******************************************************************************
															 Multi-Edit Macro
															 29-Jun-95  12:08

  Function: Control function for comment support macros.  Autodetects whether
						to comment or uncomment a code block.


							 Copyright (C) 1994-95 by American Cybernectic, Inc.
********************************************************************( ldh )***/
{
	int TRefresh = Refresh;
	int TPersistent_Blocks = Persistent_Blocks;
	int bCommentTheCode;
	int Jx;

	str TStr[ Max_Line_Length ];

	struct tCommentChars rCC;

	Push_Undo;
	Refresh = False;
	Persistent_Blocks = True;

	GetCommentChars( rCC );

 	// ... insert code ... comment or uncomment code block
	if ( ( ( rCC.szOpenComment1 != "" ) && ( rCC.szCloseComment1 != "" ) ) ||
			( rCC.szEOLComment1 != "" ) ) {
//			if ( Marking ) {
//				Block_End;
//			}
		// using the first line or current line,
		// determine whether to comment code or uncomment code

		// ( there is no "toggle comments/uncomments in code block" !!! )
		bCommentTheCode = True;
		Mark_Pos;
		if ( CursorInBlock( True ) ) {
			Goto_Line( Block_Line1 );
			Goto_Col( Block_Col1 );
		}
		else {
			Goto_Col( 1 );										// No block marked, use line
		}
		TStr = Get_Line( );
		if ( ( Jx = Length( rCC.szEOLComment1 ) ) != 0 ) {
			if ( Lower( Copy( TStr, C_Col, Jx ) ) == rCC.szEOLComment1 ) {
				bCommentTheCode = False;
				goto Process;
			}
		}
		if ( ( Jx = Length( rCC.szEOLComment2 ) ) != 0 ) {
			if ( Lower( Copy( TStr, C_Col, Jx ) ) == rCC.szEOLComment2 ) {
				bCommentTheCode = False;
				goto Process;
			}
		}
		if ( ( Jx = Length( rCC.szOpenComment1 ) ) != 0 ) {
			if ( Lower( Copy( TStr, C_Col, Jx ) ) == rCC.szOpenComment1) {
				bCommentTheCode = False;
				goto Process;
			}
		}
		if ( ( Jx = Length( rCC.szOpenComment2 ) ) != 0 ) {
			if ( Lower( Copy( TStr, C_Col, Jx ) ) == rCC.szOpenComment2) {
				bCommentTheCode = False;
			}
		}

Process:
		Goto_Mark;
		if ( bCommentTheCode ) {
			_CommentCode( rCC );
		}
		else {
			_UncommentCode( rCC );
 		}
//		Block_Off;
	}
	Pop_Undo;
	Persistent_Blocks = TPersistent_Blocks;
	Refresh = TRefresh;

}  // Comment

void CommentCode( )
/******************************************************************************
															 Multi-Edit Macro
															 29-Jun-95  12:11

  Function: Translates current block mark into a comment block
							If Block_Stat = 0,  current line using open,close comment string
															1,  current line using eol comment string
															2,  remainder of current line using eol string
															3,  start,end block mark with comment chars

							 Copyright (C) 1995 by American Cybernectic, Inc.
********************************************************************( ldh )***/
{
	struct tCommentChars rCC;

	GetCommentChars( rCC );
	_CommentCode( rCC );

}  // CommentCode

void UnCommentCode( )
/******************************************************************************
															 Multi-Edit Macro
															 29-Jun-95  12:11

  Function: Translates current block mark to uncommented code block.

							 Copyright (C) 1995 by American Cybernectic, Inc.
********************************************************************( ldh )***/
{
	struct tCommentChars rCC;

	GetCommentChars( rCC );
	_UncommentCode( rCC );

}  // UnCommentCode

#else	// ifndef Windows
void CommentCode( )
/******************** Multi-Edit VOID Macro Function ************************

 NAME:        CommentCode

 DESCRIPTION: Translates current block mark into a comment block
							If block_stat = 0,  current line using open,close comment string
															1,  current line using eol comment string
															2,  remainder of current line using eol string
															3,  start,end block mark with comment chars

 PARAMETERS:  None

 RETURNS:     (void)

 COMMENTS:

 NOTES:       NOTES: Beware of creating nested comments.  Most languages
							do not support them.


*****************************10-06-94 01:53pm*******************************/
{
	int jx;
	int sv_ins = insert_mode;
	int sv_refresh = refresh;
	int sv_pb = persistent_blocks;
	str tstr;


	str szFilExt;
	str szExtRef;
	str szOpenComment;
	str szCloseComment;
	str szEOLComment;

	str szOpenComment1, szOpenComment2;
	str szCloseComment1, szCloseComment2;
	str szEOLComment1, szEOLComment2;

	str szLanguageType;
	str szLanguageRecord;

	push_undo;
	mark_pos;

	refresh = false;
	persistent_blocks = True;

	szFilExt = get_extension(file_name);
	rm('FIND_EXT /EXT=.'+szFilExt);
	szExtRef = return_str;
	szLanguageType = Parse_Str( "\x7F" + "LS=", Global_Str( szExtRef ) );

	rm('GET_DB_RECORD '
				+'/F=MECONFIG'
				+'/NDF=1'
				+'/DPT=LANGUAGE.DB'
				+'/GLO=!GSZ_LANGREC!'
				+'/DBF=LANG'
				+'/FV='+szLanguageType
	);

	if ( return_int == 1 )
	{
		szOpenComment1  = Parse_Str( "\x7F" + "OC1=", gszLanguageRecord );
		szCloseComment1 = Parse_Str( "\x7F" + "CC1=", gszLanguageRecord );
		szEOLComment1   = Parse_Str( "\x7F" + "EOL=", gszLanguageRecord );
		szOpenComment2  = Parse_Str( "\x7F" + "OC2=", gszLanguageRecord );
		szCloseComment2 = Parse_Str( "\x7F" + "CC2=", gszLanguageRecord );
		szEOLComment2   = Parse_Str( "\x7F" + "EOL2=", gszLanguageRecord );
	}
	else
	{
		// die (do nothing, maybe a message)
	}


	if ( szOpenComment1 == '' )
	{
		szOpenComment = szOpenComment2;
	}
	else
	{
		szOpenComment = szOpenComment1;
	}

	if ( szCloseComment1 == '' )
	{
		szCloseComment = szCloseComment2;
	}
	else
	{
		szCloseComment = szCloseComment1;
	}

	 if ( szEOLComment1 == '' )
	{
		szEOLComment = szEOLComment2;
	}
	else
	{
		szEOLComment = szEOLComment1;
	}

	if ( (szOpenComment == '') &&
			 (szCloseComment == '') &&
			 (szEOLComment == '')
		 )
	{
	}
	else
	{
		if ( marking )
		{
			block_end;
		}
		switch ( block_stat )
		{
			case 3 :                  // stream mark - open and close
				insert_mode = true;

				if ( szOpenComment == '' )
				{
					for ( jx = block_line1; jx <= block_line2; jx++ )
					{
						goto_line(jx);
						if ( jx == block_line1 )
						{
							goto_col(block_col1);
						}
						else if ( (block_col2 == 0) && (block_line2 == jx) )
						{
							break;
						}
						else
						{
							goto_col(1);
						}

						if ( shorten_str(get_line) != '' )
						{
								text(szEOLComment);
						}

					}

				}
				else
				{

					goto_line(block_line2);
					goto_col(block_col2);
//          if ( (block_col2 == 0) && (!stream_block_mode) )
//          {
//            up;
//            eol;
//          }
//          else
//          {
						goto_col(block_col2+1);
//          }
					text(szCloseComment);

					goto_line(block_line1);
					goto_col(block_col1);
					text(szOpenComment);
				}

				break;

			case 2 :                  // column mark - use eol if available
																//               else use open,close

				insert_mode = false;
				for ( jx = block_line1; jx <= block_line2; jx++ )
				{
					goto_line(jx);
					goto_col(block_col1);

					if ( shorten_str(get_line) != '' )
					{
						if ( szEOLComment != '' )
						{
							insert_mode = true;
							text(szEOLComment);
						}
						else
						{
							tstr = copy(get_line,block_col1,length(get_line)-block_col1+1);
							text(szOpenComment+tstr+szCloseComment);
						}
					}

				}
				insert_mode = true;
				break;

			case 1 :                  // line mark     - try eol, else open,close
				insert_mode = true;
				for ( jx = block_line1; jx <= block_line2; jx++ )
				{
					goto_line(jx);
					goto_col(1);

					if ( shorten_str(get_line) != '' )
					{
						if ( szEOLComment != '' )
						{
							text(szEOLComment);
						}
						else
						{
							insert_mode = false; // overwrite
							text(szOpenComment+get_line+szCloseComment);
							insert_mode = true;
						}
					}
				}
				break;

			case 0 :                  // no block mark - open and close line
			default:
				if ( shorten_str(get_line) != '' )
				{
					if ( szEOLComment == '' )
					{
						put_line(szOpenComment+get_line+szCloseComment);
					}
					else
					{
						put_line(szEOLComment+get_line);
					}
				}
				break;
		}
	}

	insert_mode = sv_ins;
	goto_mark;

	pop_undo;
	block_off;
	persistent_blocks = sv_pb;
	refresh = sv_refresh;

}  // CommentCode

void UnCommentCode( )
/******************** Multi-Edit VOID Macro Function ************************

 NAME:         UnCommentCode

 DESCRIPTION:  Translates current block mark to uncommented code block

 PARAMETERS:   None

 RETURNS:      void

 COMMENTS:

 NOTES:       Beware of creating nested comments.  Most languages
							do not support them.

*****************************10-13-94 03:34pm*******************************/
{
	int jx;
	int sv_ins = insert_mode;
	int sv_refresh = refresh;
	int sv_pb = persistent_blocks;
	str tstr;

	char search_begin_char = '%';
	str if_begin_char = '';

	int comment_column_start;

	str srchkey;
	str szFilExt;
	str szExtRef;
	str szOpenComment;
	str szCloseComment;
	str szEOLComment;

	str szOpenComment1, szOpenComment2;
	str szCloseComment1, szCloseComment2;
	str szEOLComment1, szEOLComment2;

	str szLanguageType;
	str szLanguageRecord;

	push_undo;
	mark_pos;

	/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */   refresh = false ;

	persistent_blocks = True;
	comment_column_start = 0;
	szFilExt = get_extension(file_name);
	rm('FIND_EXT /EXT=.'+szFilExt);
	szExtRef = return_str;
	szLanguageType = parse_str( "\x7F" + "LS=", Global_Str( szExtRef ));

	rm('GET_DB_RECORD '
				+'/F=MECONFIG'
				+'/NDF=1'
				+'/DPT=LANGUAGE.DB'
				+'/GLO=!GSZ_LANGREC!'
				+'/DBF=LANG'
				+'/FV='+szLanguageType
	);

	if ( return_int == 1 )
	{
		szOpenComment1  = lower(parse_str( "\x7F" + "OC1=", gszLanguageRecord ) );
		szCloseComment1 = lower(parse_str( "\x7F" + "CC1=", gszLanguageRecord ) );
		szEOLComment1   = lower(parse_str( "\x7F" + "EOL=", gszLanguageRecord ) );
		szOpenComment2  = lower(parse_str( "\x7F" + "OC2=", gszLanguageRecord ) );
		szCloseComment2 = lower(parse_str( "\x7F" + "CC2=", gszLanguageRecord ) );
		szEOLComment2   = lower(parse_str( "\x7F" + "EOL2=", gszLanguageRecord ) );
	}
	else
	{
		// die (do nothing, maybe a message)
	}


	if ( (szOpenComment1  == '') &&
			 (szCloseComment1 == '') &&
			 (szEOLComment1   == '') &&
			 (szOpenComment2  == '') &&
			 (szCloseComment2 == '') &&
			 (szEOLComment2   == '')
		 )
	{
	}
	else
	{
		if ( marking )
		{
			block_end;
		}
		switch ( block_stat )
		{
			case 3 :                  // stream mark - open and close
				insert_mode = false;
				goto_line(block_line1);
				goto_col(block_col1);
				if ( szEOLComment1 != '' )
				{
					if ( lower(copy(get_line,block_col1,svl(szEOLComment1))) == szEOLComment1)
					{
					}
				}
				if ( szEOLComment2 != '' )
				{
					if ( lower(copy(get_line,block_col1,svl(szEOLComment2))) == szEOLComment2)
					{
					}
				}
				if ( szOpenComment1 != '' )
				{
					if ( lower(copy(get_line,block_col1,svl(szOpenComment1))) == szOpenComment1)
					{
						mark_pos;
						goto_line(block_line2);
						goto_col(block_col2);
						if ( lower(copy(get_line,block_col2-svl(szCloseComment1)+1,svl(szCloseComment1))) == szCloseComment1 )
						{
							goto_col(block_col2-svl(szCloseComment1)+1);
							del_chars(svl(szCloseComment1));
							goto_mark;
							del_chars(svl(szOpenComment1));
							goto stream_removal_done;
						}
						else
						{
							pop_mark;
						}
					}
				}
				if ( szOpenComment2 != '' )
				{
					if ( lower(copy(get_line,block_col1,svl(szOpenComment2)+1)) == szOpenComment2)
					{
						mark_pos;
						goto_line(block_line2);
						goto_col(block_col2-svl(szCloseComment2)+1);
						if ( lower(copy(get_line,block_col2-svl(szCloseComment2),svl(szCloseComment2))) == szCloseComment2 )
						{
							goto_col(block_col2-svl(szCloseComment2));
							del_chars(svl(szCloseComment2));
							goto_mark;
							del_chars(svl(szOpenComment2));
							goto stream_removal_done;
						}
						else
						{
							pop_mark;
						}
					}
				}

stream_removal_done:

				break;

			case 2 :                  // column mark - use eol if available
																//               else use open,close

				insert_mode = false;
				for ( jx = block_line1; jx <= block_line2; jx++ )
				{
					goto_line(jx);
					goto_col(block_col1);

					if ( shorten_str(get_line) != '' )
					{

						if ( szEOLComment1 != '' )
						{
							if ( lower(copy(get_line,block_col1,svl(szEOLComment1))) == szEOLComment1)
							{
								del_chars(svl(szEOLComment1));
								goto column_removal_done;
							}
						}
						if ( szEOLComment2 != '' )
						{
							if ( lower(copy(get_line,block_col1,svl(szEOLComment2))) == szEOLComment2)
							{
								del_chars(svl(szEOLComment2));
								goto column_removal_done;
							}
						}
						if ( szOpenComment1 != '' )
						{
							if ( lower(copy(get_line,block_col1,svl(szOpenComment1))) == szOpenComment1)
							{
								goto_line(jx);
								goto_col(block_col1);
								comment_column_start = block_col1;
								call uncomment_line;
								goto column_removal_done;
							}
						}
						if ( szOpenComment2 != '' )
						{
							if ( lower(copy(get_line,block_col1,svl(szOpenComment2)+1)) == szOpenComment2)
							{
								goto_line(jx);
								goto_col(block_col1);
								comment_column_start = block_col1;
								call uncomment_line;
								goto column_removal_done;
							}
						}
					}
column_removal_done:
				}
				insert_mode = true;
				break;

			case 1 :                  // line mark     - try eol, else open,close
				insert_mode = true;
				for ( jx = block_line1; jx <= block_line2; jx++ )
				{
					goto_line(jx);
					call uncomment_line;
				}
				break;

			case 0 :                  // no block mark - uncomment current line
			default:

				call uncomment_line;
				break;
		}
	}
	goto uc_exit;


Uncomment_Line:
	if ( !comment_column_start )
	{
		comment_column_start = 1;
		if_begin_char = search_begin_char;
	}
	else
	{
		if_begin_char = '';
	}
	if ( szEOLComment1 != '' )
	{

		if ( shorten_str(get_line) != '' )
		{
			goto_col(comment_column_start);
			srchkey = '[|32|9|255]*'+szEOLComment1;
			if ( svl(if_begin_char) )
			{
				srchkey = if_begin_char + srchkey;
			}
			if ( find_text(srchkey,1,_OldExp) )
			{
				forward_till_not('|32|9|255');
				del_chars(svl(szEOLComment1));
				goto line_removal_done;
			}
		}
	}
	if ( szEOLComment2 != '' )
	{
		if ( shorten_str(get_line) != '' )
		{
			goto_col(comment_column_start);
			srchkey = '[|32|9|255]*'+szEOLComment2;
			if ( svl(if_begin_char) )
			{
				srchkey = if_begin_char + srchkey;
			}
			if ( find_text(srchkey,1,_OldExp) )
			{
				forward_till_not('|32|9|255');
				del_chars(svl(szEOLComment2));
				goto line_removal_done;
			}
		}
	}
	if ( szOpenComment1 != '' )
	{
		if ( shorten_str(get_line) != '' )
		{
			goto_col(comment_column_start);
			srchkey = '[|32|9|255]*'+make_literal(szOpenComment1);
			if ( svl(if_begin_char) )
			{
				srchkey = if_begin_char + srchkey;
			}
			if ( find_text(srchkey,1,_OldExp) )
			{
				push_undo;
				forward_till_not('|32|9|255');
				del_chars(svl(szOpenComment1));
				eol;
				pop_undo;
				if ( find_text(make_literal(szCloseComment1)+'[|32|9|255]*$',1,_OldExp|_Backward) )
				{
					del_chars(svl(szCloseComment1));
					goto line_removal_done;
				}
				else
				{
					undo;
				}
			}
		}
	}
	if ( szOpenComment2 != '' )
	{
		if ( shorten_str(get_line) != '' )
		{
			goto_col(comment_column_start);
			srchkey = '[|32|9|255]*'+make_literal(szOpenComment2);
			if ( svl(if_begin_char) )
			{
				srchkey = if_begin_char + srchkey;
			}
			if ( find_text(srchkey,1,_OldExp) )
			{
				push_undo;
				forward_till_not('|32|9|255');
				del_chars(svl(szOpenComment2));
				eol;
				pop_undo;
				if ( find_text(make_literal(szCloseComment2)+'[~|32|9|255]*$',1,_OldExp|_Backward) )
				{
					del_chars(svl(szCloseComment2));
					goto line_removal_done;
				}
				else
				{
					undo;
				}
			}
		}

	}
line_removal_done:
	comment_column_start = 0;
	ret;

uc_exit:

	insert_mode = sv_ins;
	goto_mark;

	pop_undo;
	block_off;
	persistent_blocks = sv_pb;
	refresh = sv_refresh;

}  // UnCommentCode
#endif
