Add a string at the end of each line between /* and */

Add a string at the end of each line between /* and */

6
NewbieNewbie
6

    Nov 11, 2007#1

    Hi, I need to add a string "TC" at the end of each line between /* and */ while the number of lines between each /* ... */ pair may vary. Please help. Thanks.

    Here is an example: I want to convert from:

    /* Comment1
    Comment1 cont */
    Var1
    /* Comment2 */ /* Comment3 */
    Var2
    /* Comment4
    Comment5
    Comment6
    Comment7 */
    Var3
    ...

    to

    /* Comment1 TC
    Comment1 cont */ TC
    Var1
    /* Comment2 */ /* Comment3 */ TC
    Var2
    /* Comment4 TC
    Comment5 TC
    Comment6 TC
    Comment7 */ TC
    Var3
    ...

    236
    MasterMaster
    236

      Nov 11, 2007#2

      Please read the sticky first and give us the required information. Then, what you write is not what your example shows. In line 2, there is a "TC" added outside of an /* */ pair. Which one is correct?

      6
      NewbieNewbie
      6

        Nov 11, 2007#3

        First, thanks for the reply.
        Perhaps I should restate that "I need to add a string "TC" at the end of each line between /* and */ INCLUSIVELY."

        In my example, the 1st group of /* ... */ is

        /* Comment1
        Comment1 cont */

        which has 2 lines. I would like to convert to

        /* Comment1 TC
        Comment1 cont */ TC

        Then skip 'Var1' as it's not inside any of /* ... */. The second group of /* */ is

        /* Comment2 */ /* Comment3 */

        which has 1 line. I would like to convert to

        /* Comment2 */ /* Comment3 */ TC

        (Notice that the conflict may be in here as there are indeed 2 /* */ groups within a line. But it would be okay if the macro can convert to either the above or like

        /* Comment2 */ TC /* Comment3 */ TC)

        Then skip 'Var2'. The last group of /* ... */ is

        /* Comment4
        Comment5
        Comment6
        Comment7 */

        which has 4 lines. I would like to convert to

        /* Comment4 TC
        Comment5 TC
        Comment6 TC
        Comment7 */ TC

        Then skip 'Var3'. And the search goes on until eof.

        Also, please allow me to add additional info about my version of Uedit here:

        I am using a trial version of Ultraedit v13.20, in WinXP environment, line terminator is 'Default'.

        And I prefer Ultraedit's regular expression.

        Thanks.

        6,606548
        Grand MasterGrand Master
        6,606548

          Nov 12, 2007#4

          Use following macro with the macro property Continue if search string not found activated for this macro. It does not use a regular expression engine.

          InsertMode
          ColumnModeOff
          HexOff
          Top
          TrimTrailingSpaces
          Loop
          Find "/*"
          IfNotFound
          ExitLoop
          EndIf
          EndSelect
          Key LEFT ARROW
          Key LEFT ARROW
          StartSelect
          Find Select "*/^p"
          IfSel
          Find "^p"
          Replace All SelectText " TC^p"
          EndSelect
          Key END
          Else
          ExitLoop
          EndIf
          EndLoop
          Top

          To create the macro with the code above do following:
          1. Copy the macro code above from your browser window to Windows clipboard.
          2. Start UltraEdit and open your file with the data.
          3. Click on Macro - Record, enter a macro name, disable the "Cancel" option, but enable the "Continue if search string not found" option and press button OK.
          4. Click on Macro - Stop Recording. If you see now the post macro dialog press the button Cancel.
          5. Click on Macro - Edit Macro....
          6. Select in the left macro code edit field the first 3 macro commands. Do not select the last line which contains the macro command for your configured regular expression engine.
          7. Press Ctrl+V to replace the first 3 lines with the macro code copied from the browser window.
          8. Press the button Close and confirm updating the macro with Yes.
          9. Click on Macro - Play Again. Finished!
          Best regards from an UC/UE/UES for Windows user from Austria

          6
          NewbieNewbie
          6

            Nov 13, 2007#5

            Hi, it works!!!!!!
            Thank you very much. Really appreciate.

              Nov 13, 2007#6

              Hi Mofi --- I'm studying your codes and hope that I can write something by myself soon. I think I have a good understanding of what you wrote, however I'm not up to the level that I can handle all by myself.

              Here is an extra question and I hope that you could help me one more time:

              Suppose that, in addition to the above, within each /* ...*/ group, I want to
              (1) add '/*' at the beginning of each line if the line does not start with /*, and
              (2) add '*/ TC' at the end of each line if the line does not end with */.

              Can you show me how to modify from your codes so that I can compare and learn? Many thanks.

              Here is the example, I want to convert from:

              /* Comment1
              Comment1 cont */
              Var1
              /* Comment2 */ /* Comment3 */
              Var2
              /* Comment4
              Comment5
              Comment6
              Comment7 */
              Var3
              ...

              to

              /* Comment1 */ TC
              /* Comment1 cont */ TC
              Var1
              /* Comment2 */ /* Comment3 */ TC
              Var2
              /* Comment4 */ TC
              /* Comment5 */ TC
              /* Comment6 */ TC
              /* Comment7 */ TC
              Var3
              ...

              6,606548
              Grand MasterGrand Master
              6,606548

                Nov 13, 2007#7

                Well, now we need some regular expression replaces. The problem is that when replacing something in a selected block which modifies the number of selected bytes the end position of the selection is not correct restored after the replace. Therefore further replaces on the selection can run not on the same block and the result could be not what you would expect.

                A fast but not secure macro is following:

                InsertMode
                ColumnModeOff
                HexOff
                UnixReOff
                Top
                TrimTrailingSpaces
                Loop
                Find "/*"
                IfNotFound
                ExitLoop
                EndIf
                EndSelect
                Key LEFT ARROW
                Key LEFT ARROW
                StartSelect
                Find Select "*/^p"
                IfSel
                Find RegExp "%^(/[~*]^)"
                Replace All SelectText "/* ^1"
                Key HOME
                Find RegExp "%^([~/]^)"
                Replace All SelectText "/* ^1"
                Key HOME
                Find RegExp "^([~*]/^)$"
                Replace All SelectText "^1 */"
                Key HOME
                Find RegExp "^([~/]^)$"
                Replace All SelectText "^1 */"
                Key HOME

                Find "^p"
                Replace All SelectText " TC^p"
                EndSelect
                Key END
                Else
                ExitLoop
                EndIf
                EndLoop
                Top

                But if this macro works or not depends on the line below the selected block and how large the selected block is and how many bytes are inserted by every replace.

                Key HOME is not a really good method to restore the correct end position for the selection, especially if the line below the block starts with spaces or tabs and you have configuration setting Home Key always Goto column 1 not enabled as I have.

                Here is a better solution. If first opens a new file where all the replaces for a block are done. Whenever the 2 main finds select a block in the main file, it is copied via user clipboard 9 to the new file where the replaces are done.

                A replace all does not change the cursor position and therefore 1 Top after Paste is enough. The modified block in the temporary file is then cut and pasted over the still existing selection in the main file.

                After all blocks are reformatted the new file created just for the replaces is closed without saving it.

                InsertMode
                ColumnModeOff
                HexOff
                UnixReOff
                Top
                TrimTrailingSpaces
                NewFile
                NextWindow
                Clipboard 9
                Loop
                Find "/*"
                IfNotFound
                ExitLoop
                EndIf
                EndSelect
                Key LEFT ARROW
                Key LEFT ARROW
                StartSelect
                Find Select "*/^p"
                IfSel
                Copy
                PreviousWindow
                Paste
                Top
                Find RegExp "%^(/[~*]^)"
                Replace All "/* ^1"
                Find RegExp "%^([~/]^)"
                Replace All "/* ^1"
                Find RegExp "^([~*]/^)$"
                Replace All "^1 */"
                Find RegExp "^([~/]^)$"
                Replace All "^1 */"
                Find "^p"
                Replace All " TC^p"
                SelectAll
                Cut
                NextWindow
                Paste
                EndSelect
                Key END
                Else
                ExitLoop
                EndIf
                EndLoop
                Top
                PreviousWindow
                CloseFile NoSave
                ClearClipboard
                Clipboard 0

                Note: The macro property Continue if search string not found must be checked for both macro versions.

                If you want to understand the regular expressions, look into help of UltraEdit for page Regular Expressions on the table for the UltraEdit Syntax.

                Note: The asterisk * inside [~] is interpreted always as normal character and not as regular expression character. It could be also escaped like [~^*]. But most regular expression characters are inside [...] interpreted as normal characters.
                Best regards from an UC/UE/UES for Windows user from Austria

                6
                NewbieNewbie
                6

                  Nov 13, 2007#8

                  Man, this is fast, I really appreciate your help.

                  I tried both macro and they all ran fine in my simple example.

                  The 1st 'not secure' macro:
                  (1) You mentioned that the 'not secure' macro may run into problem that the end position may not be restored correctly after replace, could you give an example to show?
                  (2) there are several 'key HOME' there, do they bring the cursor back to the start position of the CURRENT line, or the start position of the SELECTED TEXT? I don't quite understand why you have to put 'key HOME' there?

                  The 2nd macro:
                  (1) If I understand correctly, the 'Top' is put to resolve the issue of 'key HOME' in the 1st macro, and you mentioned that since 'Replace All' does not change the cursor position, hence only 1 'Top' after 'Paste' is enough. But then, 'Replace All' is also used in the 1st macro too, why then 4 'Key HOME' are needed there?

                  This is very helpful, thanks a lot.
                  BTW, just checked with IT, my company has corporate lisense with Uedit, which is very good to me. Thanks again, looking forward to hearing from you soon.

                  6,606548
                  Grand MasterGrand Master
                  6,606548

                    Nov 14, 2007#9

                    Insert in the first macro the command ExitMacro after second Replace All SelectText "/* ^1" before command Key HOME and run the macro on your example. The initial Find Select "*/^p" selects the block

                    /* Comment1
                    Comment1 cont */


                    and the cursor is on start of the next line (= after the line ending of the line with */). But as you now can see after the second replace (the first does nothing on your example) the selection is expanded and does not end anymore after */^p as before. Key HOME works here because the next line is not a blank line, does not start with a white-space character and is long enough to let the selection not expand over an additional line.

                    Now delete from your test file everything above /* Comment4, insert a blank line above Var3 and run the not secure macro with the ExitMacro command again. You will see that the cursor position (= end of selection) after the replace is completely wrong and Key HOME will not restore anymore the correct position.

                    Key HOME moves the cursor to start of the current line and because of selection mode is still active (activated with StartSelect, but EndSelect is below the replaces) the selection is also modified. It is like you have made a selection and press Shift+Home to change the cursor position and also the selection if the current selection ends on the current cursor position which is for example column 5.

                    The second macro avoids all the problems above because it copies the initial selection into a new file. After pasting a text the cursor is always at the end of the pasted text (= end of the temp file). The single command Top moves the cursor to top of the temp file (would be equal to start of selection in main source) and then run the same replaces as macro 1, but on whole file instead of a selected area because nothing is selected. The 5 replaces in macro 2 do not have parameter SelectText. This now always correct reformatted block is then copied back over the still selected original block in the main file.

                    If you want to understand that macro, I suggest to execute every command manually. Then you can see step by step what the macro does.

                    I have yesterday something forgotten:

                    You should insert the code block

                    Bottom
                    IfColNum 1
                    Else
                    "
                    "
                    EndIf


                    between the commands UnixReOff and Top. That makes sure that the last line of the file has also a line ending and is therefore really a line and not just a string at end of file. This is important if the last line of the file ends with */ but without a carriage return + line-feed (= no DOS line ending at end of the file).
                    Best regards from an UC/UE/UES for Windows user from Austria

                    6
                    NewbieNewbie
                    6

                      Nov 15, 2007#10

                      THIS IS VERY CLEAR AND HELPFUL!!!!

                      Thanks a lot Mofi.