Recursive Replacement in File

Recursive Replacement in File

3
NewbieNewbie
3

    Dec 04, 2007#1

    I'm using UE 13.20+4 - RegEx Unix Style

    in my C-sources i have to format comments.

    Example - Something like that

    Code: Select all

      /**************************************************/
      /* Strukturverschiebung ? - Exception             */
    
          /**********************************************/
          /* Eingabedaten pruefen - technisch / fachlich*/
          /* Nr_Konto befuellt ?                        */
    Should look like

    Code: Select all

      /*********************************************************************
       * Strukturverschiebung ? - Exception    
       ********************************************************************/
    
          /*****************************************************************
           * Eingabedaten pruefen - technisch / fachlich    
           * Nr_Konto befuellt ?  
           ****************************************************************/
    The length of comments never exceeds 72 for each line
    The first /* should start at position where the old /* resits, the length of each line is 72 and the last */ is at row 72

    To find the affecting lines this regex is used: (\s+/\*+\*/\r)(\s+/\*\s+[\w\s\d-?.>!\*>=/]+\*/)+

    How can I replace those comments ?

    Thanks in advance.

    EDIT:
    A macro for inserting a comment with correct format is:

    Code: Select all

    InsertMode
    ColumnModeOff
    HexOff
    UnixReOff
    "/"
    Loop 
    "*"
    IfColNum 72
    ExitLoop
    EndIf
    EndLoop
    "
     * 
    "
    Loop 
    "*"
    IfColNum 72
    ExitLoop
    EndIf
    EndLoop
    "/"
    Key UP ARROW
    Kind regards
    Stefan
    from Germany

    6,606548
    Grand MasterGrand Master
    6,606548

      Dec 05, 2007#2

      Here is a macro which hopefully works for you. It works for your example. The right alignment to column 72 currently works only if there are no tabs before /*** or ***, only 0 or more spaces. This could be checked and corrected also with additional code if necessary. It does not modify already correct formatted comment blocks except the starting or ending line start with tab(s).

      The macro is a little bit tricky because nesting of loops is not possible and there is also no search within a selection. Both would be possible in the script environment.

      The macro property Continue if a Find with Replace not found or Continue if search string not found must be checked for this macro.

      InsertMode
      ColumnModeOff
      HexOff
      UnixReOff
      Bottom
      IfColNum 1
      "
      "
      Else
      "

      "
      EndIf
      Top
      TrimTrailingSpaces
      Clipboard 9
      Loop
      IfSel
      Find RegExp "%^([ ^t]++/^*[ ^t]^)"
      Replace All SelectText "^1"
      IfNotFound
      SelectLine
      EndSelect
      Key UP ARROW
      Paste
      Key UP ARROW
      Find "/"
      Replace " "
      Else
      SelectLine
      EndSelect
      Key UP ARROW
      Key DOWN ARROW
      SelectLine
      EndIf
      Else
      Find RegExp "%[ ^t]++/^*^*^*+/^n"
      IfNotFound
      ExitLoop
      EndIf
      Copy
      EndSelect
      Key UP ARROW
      Key END
      Key BACKSPACE
      Key DOWN ARROW
      SelectLine
      EndIf
      EndLoop
      Bottom
      Key BACKSPACE
      Top
      Find RegExp "%^([ ^t]++^)/^(^*[~^*]+^)^*/"
      Replace All "^1 ^2"
      TrimTrailingSpaces
      Find "***"
      Replace All "**************************************"
      Find RegExp "%^(???????????????????????????????????????????????????????????????^*^*^*^*^*^*^*^*^)*/$"
      Replace All "^1/"
      Find RegExp "%^(????????????????????????????????????????????????????????????????^*^*^*^*^*^*^*^*^)*$"
      Replace All "^1"
      ClearClipboard
      Clipboard 0

      Add UnixReOn or PerlReOn (v12+ of UE) at the end of the macro if you do not use UltraEdit style regular expressions by default - see search configuration. Macro command UnixReOff sets the regular expression option to UltraEdit style.

      Here is the code again with indentations for better understanding. See Macro examples and reference for beginners and experts how to highlight and edit such UEM (UltraEdit Macro code) files.

      Code: Select all

          InsertMode
          ColumnModeOff
          HexOff
          UnixReOff
      /*! Often the last line of a file is not terminated with a line ending.
          Check this for the current file too and insert the line ending if
          the last line is not terminated. Additionally it is possible that
          at the end of the file is a comment block which should be converted
          into the new format. The following method to detect the end of such
          a comment block requires always a line below a comment block with
          or without any characters. So add always an additional extra line. !*/  
          Bottom
          IfColNum 1
              "
              "
          Else
              "
          
              "
          EndIf
          Top
      /*! Back at top of the file delete all spaces and tabs at end of all lines.
          That makes it easier for the following regular expressions. And switch
          to clipboard 9 to not destroy content of standard Windows clipboard. !*/
          TrimTrailingSpaces
          Clipboard 9
      /*! The following loop copies the header line of a comment block and inserts
          it at bottom of the comment block. Also the required modifications at
          end of the header line and start of the footer line are done in this
          loop. The loop is executed until no further header line in wrong format
          is found anymore in the file.
          Nesting of loops and searching inside a selection only is not possible
          in macros. To avoid a sub macro a trick is used to determine in a single
          loop if a search for the next header line in wrong format or for the end
          of the comment block should be done. If there is currently a selection
          search for the end of the comment block. If there is no selection search
          for the next header line. !*/
          Loop
              IfSel
      /*! Does the currently selected line start with 0 or more occurrences
          of spaces or tabs, followed by /* and an additional space or tab?
          A search within a selection is not possible, but a replace all in
          selected text. So use this workaround. The replace itself does not
          change anything in any case. !*/
                  Find RegExp "%^([ ^t]++/^*[ ^t]^)"
                  Replace All SelectText "^1"
                  IfNotFound
      /*! This line does not contain "/* " at start of the line with or without
          preceding white-space(s). So it is probable not a comment line which
          means the end of the comment block is found. The before copied header
          line must be inserted at start of this line. The problem is that
          although the replace has not really changed something, the selection
          and also the cursor position could be modified by UltraEdit and the
          cursor is not anymore at column 1 of the line below. UltraEdit could
          have moved the cursor back 1 or more characters. Best method to restore
          the selection and at the same time the correct cursor position is to
          simply re-select the line. Then the cursor is surely at start of the
          next line. Now stop selection mode and move the cursor up to the just
          before selected line without "/* " at start of the line. Insert here
          the header line and replace the first / by a space to get correct
          format for the footer line of a block. !*/
                      SelectLine
                      EndSelect
                      Key UP ARROW
                      Paste
                      Key UP ARROW
                      Find "/"
                      Replace " "
                  Else
      /*! This selected line starts with "/* " and so it is probable a comment
          line of the current comment block. Restore the cursor position with
          re-selecting the line (see above for the reason), stop selection mode,
          unselect the line by moving the cursor up and down and select the next
          line for the next test. !*/
                      SelectLine
                      EndSelect
                      Key UP ARROW
                      Key DOWN ARROW
                      SelectLine
                  EndIf
              Else
      /*! Nothing selected means search for header line of a comment block in
          wrong format. Such a line can have preceding white-space(s). Important
          is that it starts with "/***", can have more *, but no other characters
          before the line ends with a / and the line-feed (UNIX line endings).
          If such a line is not found anymore, exit the loop. If such a line was
          found, copy it to user clipboard 9, delete the / from end of the line
          and select the line below because now the macro have to search for the
          end of the wrong formatted comment block. !*/
                  Find RegExp "%[ ^t]++/^*^*^*+/^n"
                  IfNotFound
                      ExitLoop
                  EndIf
                  Copy
                  EndSelect
                  Key UP ARROW
                  Key END
                  Key BACKSPACE
                  Key DOWN ARROW
                  SelectLine
              EndIf
          EndLoop
      /*! After the loop the cursor is more or less at the end of the file.
          Move to end of file and delete the extra line inserted at start
          of the macro because it is not needed anymore. !*/
          Bottom
          Key BACKSPACE
          Top
      /*! Back at top of the file run a replace all to reformat all comment lines
          (between the header and footer lines) which still start with "/*" and
          end with */. The next character after "/*" can be everything except an
          asterisk *. This is just for security. This replace replaces the / by
          a spaces and removes the */. The rest of the line is not changed.
          Note: It replaces also /* ... */ to * ... outside a comment block! !*/
          Find RegExp "%^([ ^t]++^)/^(^*[~^*]+^)^*/"
          Replace All "^1 ^2"
      /*! There will be surely many unnecessary trailing spaces now which should
          be deleted too. !*/
          TrimTrailingSpaces
      /*! All header and footer lines of a comment block should end at column 72.
          For fast granting this requirement replace all strings with 3 * by a
          string with many more *. 35 extra * per 3 * string should be enough. !*/
          Find "***"
          Replace All "**************************************"
      /*! Now all header and footer lines of every comment block should have far
          too many *. With 2 simple regular expressions short them exactly to
          72 characters per line, first the footer, then the header lines. This
          quick method does not work for header and footer lines with preceding
          tabs if a tab is defined to be a place holder for more than 1 space. !*/
          Find RegExp "%^(???????????????????????????????????????????????????????????????^*^*^*^*^*^*^*^*^)*/$"
          Replace All "^1/"
          Find RegExp "%^(????????????????????????????????????????????????????????????????^*^*^*^*^*^*^*^*^)*$"
          Replace All "^1"
      //  Clear the clipboard 9 to free RAM and switch back to Windows clipboard.
          ClearClipboard
          Clipboard 0
      /*! Activate UnixReOn or PerlReOn (v12+ of UE) here at the end of the macro
          if you do not use UltraEdit style regular expressions by default - see
          search configuration. Macro command UnixReOff at start of the macro
          sets the regular expression option to UltraEdit style. !*/
      //  UnixReOn
      //  PerlReOn
      Best regards from an UC/UE/UES for Windows user from Austria

      3
      NewbieNewbie
      3

        Dec 05, 2007#3

        Hey, I'm really impressed.

        There are a few things wrong:
        The first line of the comment /******************** is closing with a */ - thats wrong - no problem i guess
        the line after the comment : *******************/ is missing.

        ;-)

        My examples look like:

        Code: Select all

          /*************************************************************/
           * Strukturverschiebung ? - Exception             
        
              /*********************************************************/
               * Eingabedaten pruefen - technisch / fachlich
               * Nr_Konto befuellt ? 

        Meanwhile I did an update to 13.20+5 same results

        Thanks for your work so far - it's great :!:
        it's perfect when missing stuff is handled :-)

        Kind regards
        Stefan
        from Germany

        6,606548
        Grand MasterGrand Master
        6,606548

          Dec 05, 2007#4

          My macro produces exactly the output you want for your input. According to your description it looks like the loop does nothing and I think the reason is ^p in the regular expression string %[ ^t]++/^*^*^*+/^p which means DOS line ending (carriage return + line-feed).

          I guess, your file is not a DOS file or at least converted temporarily to DOS. Do you see UNIX in the status bar at bottom of the UltraEdit window? Yes, then replace ^p by ^n in the regular expression string and it should work.

          Next time don't forget the encoding and line ending format of the file when asking for a find/replace/regular expression or macro help.
          Best regards from an UC/UE/UES for Windows user from Austria

          3
          NewbieNewbie
          3

            Dec 05, 2007#5

            You're right. It's UNIX-Format, sorry.

            Now it does the things wanted - perfect.

            I have a nice effect with the macro.

            If I have only a comment-line like /**********************************/
            it's now replaced by
            /*******************************************************
            ******************************************************/

            No great problem ;-)

            I'd like to understand how the macro works, so that I can use it for other purposes and change it as I need it.

            Kind regards
            Stefan
            from Germany

            6,606548
            Grand MasterGrand Master
            6,606548

              Dec 06, 2007#6

              I have edited my first post and replaced the UEM version with a new one which contains lots of comments which hopefully helps you to understand the macro.

              For the problem with /**********************************/ either use a replace all at end of the macro to replace

              /*******************************************************
              ******************************************************/


              back to a single line comment or adapt the macro in the lower Else branch after finding the header line of the comment block to check immediately if the next line is also a comment line.
              Best regards from an UC/UE/UES for Windows user from Austria