.
.   
NEdit.org
   .

Home
 - News - Download - Documentation - Search - FTP     
.
.
  

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  

  
Visit our sponsor
Check Metrolink

© NEdit.org
1999-2001
All rights reserved


.