|
Trace IF / ELSE / END IF
[Back]
This macro traces matching IF / THEN
/ ELSE / END IF statements for VHDL. It's probably not
hard to modify it for other languages. Just select either an IF,
ELSE, ELSIF or END IF statement, start the
macro and it will find the next IF / ELSE / ELSIF
/ END IF statement. Nesting of IF's is allowed, so it's
just like matching braces. Selecting END IF and activating the
macro will wrap back to the matching IF.
level = 0
# if selection != "END IF": search next matching ELSE/ELSIF/END IF command:
if (search_string(get_selection(), "[eE][nN][dD][ \t]*[iI][fF]", 0, "regex") == -1)
# Analyse from selection to EOF:
for (i=$selection_end; i<$text_length; i++) {
# VHDL comment: skip to EOL
if (search_string(get_range(i, i+2), "--", 0) != -1) {
i = search("$", i, "regex")
# If command "IF" is found: increase nesting-level:
} else if (search_string(get_range(i, i+2), "[iI][fF]", 0, "regex") != -1) {
level = level + 1
# If command "ELSIF" is found: select or skip depending on current nesting-level:
} else if (search_string(get_range(i, i+5), "[eE][lL][sS][iI][fF]", 0, "regex") != -1) {
if (level == 0) {
select(i, i+5)
break
} else {
i = i + 5 # skip to prevent the "IF" to be misinterpreted
}
# If command "IF" is found: select it:
} else if ((search_string(get_range(i, i+4), "[eE][lL][sS][eE]", 0, "regex") != -1) &&\
(level == 0)) {
select(i, i+4)
break
# If command "END IF" is found: select it or decrease current nesting-level:
} else if (search_string(get_range(i, i+6), "[eE][nN][dD][ \t][iI][fF]", 0, "regex") != -1) {
if (level == 0) {
select(i, i+6)
break
} else {
level = level - 1
}
i = i + 6 # skip to prevent the "IF" to be misinterpreted
}
} # end of for-loop
else { # selection was "END IF"; search backwards for matching "IF":
for (i = $selection_start - 1; i >= 0; i--) {
# Search for an "IF" statement:
if (search_string(get_range(i, i+2), "[iI][fF]", 0, "regex") != -1) {
# But the "IF" may not be an "END IF" or "ELSIF":
if ((search_string(get_range(i-3, i+2), "[eE][lL][sS][iI][fF]", 0, "regex") == -1) &&\
(search_string(get_range(i-4, i+2), "[eE][nN][dD][ \t][iI][fF]", 0, "regex") == -1)) {
# First check for a comment:
linestart = search("^", i, "regex", "backward")
if (search_string(get_range(linestart, i), "--", 0) == -1) {
# If current nesting-level = 0: select, else decrease nesting-level:
if (level == 0) {
select(i, i+2)
break
} else
level = level - 1
} else
level = level # skip IF in comment
} else
level = level # skip "ELSIF" or "END IF"
} else {
# If "END IF" is found: increase current nesting-level:
if (search_string(get_range(i, i+6), "[eE][nN][dD][ \t][iI][fF]", 0, "regex") != -1) {
# First check for a comment:
linestart = search("^", i, "regex", "backward")
if (search_string(get_range(linestart, i), "--", 0) == -1)
level = level + 1
}
}
}
# Move to selection:
}
set_cursor_pos($selection_end)
This version traces #ifdef / #else /
#endif:
level = 0
# if selection != "#ENDIF": search next matching #ELSE/#ELIF/#ENDIF command:
if (search_string(get_selection(), "#[eE][nN][dD][iI][fF]", 0, "regex") == -1)
{
startpos = $selection_start
# Analyse from selection to EOF:
for (i=$selection_end; i<$text_length; i++)
{
# If command "#IFDEF" is found: increase nesting-level:
if (search_string(get_range(i, i+6), "#[iI][fF][dD][eE][fF]", 0, "regex") != -1)
{
level = level + 1
}
else
# If command "#ELIF" is found: select or skip depending on current nesting-level:
if (search_string(get_range(i, i+5), "#[eE][lL][iI][fF]", 0, "regex") != -1)
if (level == 0)
{
select(i, i+5)
break
}
else
i = i + 5 # skip to prevent the "IF" to be misinterpreted
else
# If command "#ELSE" is found: select it:
if ((search_string(get_range(i, i+5), "#[eE][lL][sS][eE]", 0, "regex") != -1) &&\
(level == 0))
{
select(i, i+5)
break
}
else
# If command "#ENDIF" is found: select it or decrease current nesting-level:
if (search_string(get_range(i, i+6), "#[eE][nN][dD][iI][fF]", 0, "regex") != -1)
{
if (level == 0)
{
select(i, i+6)
break
}
else
{
level = level - 1
}
i = i + 6 # skip to prevent the "IF" to be misinterpreted
}
}
select(startpos, $selection_end)
set_cursor_pos($selection_end)
}
else # selection was "#ENDIF"; search backwards for matching "#IFDEF":
{
endpos = $selection_end
for (i = $selection_start - 1; i >= 0; i--)
{
# Search for an "#IFDEF" statement:
if (search_string(get_range(i, i+6), "#[iI][fF][dD][eE][fF]", 0, "regex") != -1)
# If current nesting-level = 0: select, else decrease nesting-level:
if (level == 0) {
select(i, i+6)
break
}
else
level = level - 1
else
# If "#ENDIF" is found: increase current nesting-level:
if (search_string(get_range(i, i+6), "#[eE][nN][dD][iI][fF]", 0, "regex") != -1)
level = level + 1
}
select($selection_start, endpos)
set_cursor_pos($selection_start)
}
# Move to selection:
#set_cursor_pos($selection_end)
[Back]
Released on Wed, 21 Nov 2001
by
C. Denat
|
|