Substitute this pattern for that pattern EXCEPT if this is true with sed???

Substitute this pattern for that pattern EXCEPT if this is true with sed???

Post by Sune » Tue, 27 Sep 2005 04:08:44



Hi!

I want to add debug macros to my C source files. I want the word TRACE
to show up after every '{' and ';' unless ';' is preceeded by 'return'
or 'int' or 'float' etc...

Here's what I got so far:

#!/bin/sh
find /home/epkolbl/workspace/rsd2/ -name '*.c' | while read file
do
        awk '{ print $0 }' $file | sed 's/;/;TRACE/g' | sed 's/{/{TRACE/g'
done

However this piece of script adds TRACE after ';' even though it is
preceeded by 'return' etc.

I have run out of ideas. Could someone please help me?

Thanks in advance
/Sune

 
 
 

Substitute this pattern for that pattern EXCEPT if this is true with sed???

Post by Chris F.A. Johnso » Tue, 27 Sep 2005 05:18:23



> Hi!

> I want to add debug macros to my C source files. I want the word TRACE
> to show up after every '{' and ';' unless ';' is preceeded by 'return'
> or 'int' or 'float' etc...

> Here's what I got so far:

> #!/bin/sh
> find /home/epkolbl/workspace/rsd2/ -name '*.c' | while read file
> do
>    awk '{ print $0 }' $file | sed 's/;/;TRACE/g' | sed 's/{/{TRACE/g'

    Cat would have been bad enough, but awk????

 sed -e 's/;/;TRACE/g' -e 's/{/{TRACE/g' "$file"

Quote:> done

> However this piece of script adds TRACE after ';' even though it is
> preceeded by 'return' etc.

    Use awk:

awk '{ gsub("{","{TRACE") }
     /int/ || /float/ || /return/ {  ## Adjust patterns to taste
             print; next }
     { gsub(";",";TRACE"); print }' "$file"

--
    Chris F.A. Johnson                     <http://cfaj.freeshell.org>
    ==================================================================
    Shell Scripting Recipes: A Problem-Solution Approach, 2005, Apress
    <http://www.torfree.net/~chris/books/cfaj/ssr.html>

 
 
 

Substitute this pattern for that pattern EXCEPT if this is true with sed???

Post by Enrique Perez-Terro » Tue, 27 Sep 2005 05:34:04



> Hi!

> I want to add debug macros to my C source files. I want the word TRACE
> to show up after every '{' and ';' unless ';' is preceeded by 'return'
> or 'int' or 'float' etc...

> Here's what I got so far:

> #!/bin/sh
> find /home/epkolbl/workspace/rsd2/ -name '*.c' | while read file
> do
>    awk '{ print $0 }' $file | sed 's/;/;TRACE/g' | sed 's/{/{TRACE/g'
> done

> However this piece of script adds TRACE after ';' even though it is
> preceeded by 'return' etc.

> I have run out of ideas. Could someone please help me?

For starters, throw out awk here. You can give multiple commands
to sed, and sed will execute each in turn on each line.

     sed -e 's/;/;TRACE/g' -e 's/{/{TRACE/g' $file

Then make sure you save the file. Getting the whole shebang on the screen
is OK while learning shell programming, but if you also plan to compile
it...

     find /home/epkolbl/workspace/rsd2 -name \*.c |
     while read file; do
        # keep the original file with extension -orig.c
         tmpfile=${file%.c}-trace.c
        bckfile=${file%.c}-orig.c
        sed -e 's/;/;TRACE/g' -e 's/{/{TRACE/g' $file > $tmpfile &&
          mv -f $file $bckfile &&
          mv -f $tmpfile $file
     done

Then let's see what we can do with the int, return and float.
I am afraid that if you want a fully correct parsing of the files
you will have to yank a few tens of thousand lines of code from the
gcc compiler, and use that to make you own rewriter.

But if you can manually ensure that the file does not contain
multiple statements on the same line when one or more of them
are declarations or returns, and if you can manually ensure that
all declarations have ';' on the same line as the 'int' or
'float', then we can do it with an approximation. Also look
out for "myinteger = (int) *chrpointer;" - you will not get
TRACE here either. Other things that will not work as you
probably want are

   typedef int i32_t;
   i32_t variable;

You probably don't want TRACE after the declaration
of "variable".

   int my_array[] = {
        ONE, /* A well known constant numeral */
        TWO  /* Another hero of the evereday life */
   };  /* to TRACE or not to TRACE, that's the maze. */

But given enough caveats, try this code:

        LC_ALL=C sed -e  
'/\(^\|[^_0-9A-Za-z]\)\(int\|float\|return\)\([^_0-9A-Za-z]\|$\)/ {
            p
            d
            }'  -e 's/;/;TRACE/g' -e 's/{/{TRACE/g' $file > $tmpfile &&

The four lines just above replace exactly one line in the code
further up.  You do need the other lines of the command further
up. If you include only almost all the backslashes in your copy,
dont expect it to almost work.

-Enrique

 
 
 

Substitute this pattern for that pattern EXCEPT if this is true with sed???

Post by Sune » Tue, 27 Sep 2005 07:04:04


Hi Enrique,

your script worked really well. I understand enough to poke around in
it and change it as my needs changes and new needs surface.

I could never have come up with such a eh.... thing(?)

Thanks again
/Sune

 
 
 

Substitute this pattern for that pattern EXCEPT if this is true with sed???

Post by Ed Morto » Tue, 27 Sep 2005 08:13:50



> Hi!

> I want to add debug macros to my C source files. I want the word TRACE
> to show up after every '{' and ';' unless ';' is preceeded by 'return'
> or 'int' or 'float' etc...

> Here's what I got so far:

> #!/bin/sh
> find /home/epkolbl/workspace/rsd2/ -name '*.c' | while read file
> do
>    awk '{ print $0 }' $file | sed 's/;/;TRACE/g' | sed 's/{/{TRACE/g'
> done

> However this piece of script adds TRACE after ';' even though it is
> preceeded by 'return' etc.

> I have run out of ideas. Could someone please help me?

You can't do this reliably without re-implementing the C language parser
used by your compiler. There's a YACC grammar for ANSI C available at
http://www.lysator.liu.se/c/ANSI-C-grammar-y.html if you want to do it.
Alternatively, there's a Bell Labs research project called Proteus that
I think would do exactly what you want BUT I don't know how available
Proteus is for outside use. They may want some friendly users, or they
may even be ready for prime time by now (the project started in 2003).
You can get more information on it at
http://www1.bell-labs.com/project/proteus/.

Regards,

        Ed.

 
 
 

Substitute this pattern for that pattern EXCEPT if this is true with sed???

Post by Sune » Wed, 28 Sep 2005 00:56:34


Hi Ed,

it seems Enrique's sed incantation made the trick, it's 'good enough',
I didn't expect to get it to run like a swiss clock.

YACC and what bell-labs are capable of seem to be a bit too extensive,
but thanks for helping me out.

BRs
/Olle

 
 
 

1. sed pattern replacement question with pattern duplication

I would like to duplicate an unknown pattern (e.g. xxx) which is enclosed by an opening
and closing bracket [  ] and add some more text (e.g. bbb ccc and ddd).

Example:

blah1 blah2 blah3[xxx]blah4 blah5 blah6

should be afterwards:

blah1 blah2 blah3bbbxxxcccxxxdddblah4 blah5 blah6

The brackets could occur multiple time in a row.
Other Example (this time the unknown patterns enclosed by the brackets are yyy and zzz:

foo1 foo2 [yyy]foo3 foo4[zzz]   foo5

Should be transferred to:

foo1 foo2 bbbyyycccyyydddfoo3 foo4bbbzzzccczzzddd    foo5

How do I specify this rule for an sed command ?

Matt

2. drawing program for circuit schematics

3. How sed-substitute a string that DOES NOT match my pattern...

4. Q:ftp login shell

5. Pattern Matching Not Working When Pattern Assign To A Variable

6. Adding a new function to NETFILTER.

7. ksh pattern matching when pattern is in a variable

8. turn off virtural paging in lesstif

9. grepping for pattern, and then deleting ALL the following lines after the pattern

10. grep pattern within pattern

11. Matching Line After Pattern (Pattern Occurs Multiple Times)

12. Pattern matching and extracting the data which matches the pattern

13. Replacing all patterns except last one