[kwlug disc.] how to globally find/transform patterns with matching brackets

Robert P. J. Day rpjday at mindspring.com
Sat Dec 23 11:42:37 EST 2006


  i'm sure there's an easy perl way to do this, so here's what i'm
after.  i want a general pattern-matching expression that can handle
matching parentheses.  as a single example (that should generalize to
everything else i want to do), consider a way in C language to
calculate the number of elements in an array:

  sizeof(arr)/sizeof(arr[0])

that's pretty standard and, in a large source tree, i can transform
each instance of that to a simpler form based on a macro defined as
above:

  #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
  ...
  blah = ARRAY_SIZE(arr)

using the following combination of recursive grep and perl:

MACRO=ARRAY_SIZE
...
for f in $(grep -Erl "sizeof ?\( ?([^\) ]+) *\) */ ?sizeof ?\( ?\1\[0\] ?\)" ${DIR}) ; do
  echo "${MACRO}()ing $f ..."
  perl -pi -e "s|sizeof ?\( ?([^\) ]+) ?\) ?/ ?sizeof ?\( ?\1\[0\] ?\)|${MACRO}\(\1\)|" $f
done

yes, it's hideous but it's quick and dirty and it works.  however,
there are also variants such as:

  sizeof arr / sizeof arr[0]

with no parentheses and i'd like to catch these, too.  but i want to
make sure that, if there's an opening parenthesis, there's a matching
closing parenthesis, and i'm not sure if this can be done just using
grep or egrep.

  frankly, there's a bunch of variations that all should be identified
and transformed, such as:

  sizeof(arr) / sizeoff(arr[0])
  sizeof arr/sizeof arr[0]
  sizeof arr / sizeof(*arr)

and so on.  does someone have a cute way of doing this?  currently,
i'm just handling each variation independently and that works, but i'm
always interested in a simpler, more elegant solution.

rday



More information about the KWLUG-Disc mailing list