# Peeter Joot's Blog.

• ## Archives

 binaere optionen on A start at a rudimentary perl… bubba transvere on My letter to the Ontario Energ… Kuba Ober on New faucet installation peeterjoot on Ease of screwing up C string… peeterjoot on Basement electrical now d…
• ## People not reading this blog: 6,973,738,433 minus:

• 136,548 hits

# Archive for August 6th, 2009

## dirty perl tricks. using evaluations in a replacement expression

Posted by peeterjoot on August 6, 2009

I’ve gone and done a search and replace of a return type everywhere in a certain file, and the new typedef name has more characters than the original. Now the nicely indented prologues for each function are all messed up like so:

inline SAL_CA_STATUS_TYPE SQLE_CA_CONN_ENTRY_DATA::sqleCaCeWriteSA( CASA_t * const          SAToken,
SAL_CA_PAGENAME_TYPE * const    pSaPageName,
const Uint8             newElement,
const Uint8             cond,
const Uint8             maxagg,
const Uint8             increasing,
const Uint64            input,
Uint64   * const        aggregate,
bool * const            pbDispatchError )

I want things indented by eight characters, on all the lines after the ones that start with ‘inline SAL_CA_STATUS_TYPE’ till the end brace that marks the end of the argument list. It should look like:

...
inline SAL_CA_STATUS_TYPE SQLE_CA_CONN_ENTRY_DATA::sqleCaCeWriteSA( CASA_t * const          SAToken,
SAL_CA_PAGENAME_TYPE * const    pSaPageName,
const Uint8             newElement,
const Uint8             cond,
const Uint8             maxagg,
const Uint8             increasing,
const Uint64            input,
Uint64   * const        aggregate,
bool * const            pbDispatchError )
{
...

Kind of a silly exersize in prettying things up, but the new poor formatting makes things harder to read, and is distracting for maintainance. I’ve got 44 such functions in this file and don’t want to do them manually.

Is there an easy way to indent all the lines after the first by the eight characters needed in this case? I’ve wanted to do scripted changes like this before (like add an argument to all function calls matching some pattern), so it seemed like it was worth a few minutes to play with it. Here’s what I came up with:

#!/usr/bin/perl

while (<>)
{
$p .=$_ ;
}

$p =~ s/^(inline SAL_CA_STATUS_TYPE.*?\))/foo("$1")/smeg ;
print $p ; exit ; sub foo { my$s = "@_" ;
$s =~ s/^ / /smg ; return "$s" ;
}

Here’s a breakdown of what this does and how. The first problem is that I want to operate on the whole file and not on a line by line basis. This loop:

while (<>)
{
$p .=$_ ;
}


sucks up each line from stdin and puts it all in a working variable $p. Now that I’ve got all 19000 lines of the file in a working variable (yes, I should probably split up my file;), I want to match all instances of any lines that start with ‘inline SAL_CA_STATUS_TYPE’ until the first ending brace for the end of the argument list. I don’t have any function pointer arguments so I can match til the first ) after the starting expression. So, a match expression that does the job is: /^inline SAL_CA_STATUS_TYPE.*?\)/  The caret says match the beginning of the line, and since ) is a special character in perl I have to escape it. I also don’t want to match past the first ) so I use a non-greedy pattern ‘.*?’ … meaning match anything but stop at the earliest point based on context. Next I want to put all of this into a variable I can refer to in the replacement expression (that is$1 ), so wrap the whole thing in in the capture pattern (). That leaves me with:

/^(inline SAL_CA_STATUS_TYPE.*?\))/


Since I want to do this for all matches, I need the g modifier at the end, and since the text is multiline, I need /sm too. If I wanted a pure text change at this point, I could do something like:

$p =~ s/^(inline SAL_CA_STATUS_TYPE.*?\))/blah$1blah/smg ;


This would wrap all instances of the pattern with blah blah, like a quoting operation. What I want though, is to extract all matches to this first pattern and do more to it. The /e modifier does that, and allows the replacement expression to be code. I wrote a quick function that in turn did my second search and replace:

sub foo
{
my $s = "@_" ;$s =~ s/^ /         /smg ;

return "\$s" ;
}


In this helper function, I replace all lines starting with one character with nine, and voila I’m done. Takes longer to explain this throw away script than to write it, and I now have a template for other similar automated changes in the future.

## Refreshed online version of Geometric Algebra book.

Posted by peeterjoot on August 6, 2009

My exploratory physics notes using Geometric Algebra have now been refreshed with the following recent updates:

• July 2, 2009 (ch73) Space time algebra solutions of the Maxwell equation for discrete frequencies
• July 17, 2009 (ch38) Stokes theorem applied to vector and bivector fields
• July 21, 2009 (ch39) Stokes theorem derivation without tensor expansion of the blade
• July 27, 2009 (ch107) Bivector form of quantum angular momentum operator
• July 30, 2009 (ch74) Transverse electric and magnetic fields

These were all first posted in this blog.

The first covers transverse waves in vacuum, and uncovers the solution utilizing a Fourier transform of the Maxwell equation.

The angular momentum article is a factorization of the spatial (or four vector space-time) gradient into $x \wedge \nabla$ and $x \cdot \nabla$ terms.  This factorization is seen in the context of quantum mechanics treating the angular momentum operator in spherical polar coordinates, but only in coordinate form.  I don’t think it is normal to see this outside of quantum mechanics, but there is nothing intrinsically quantum about this projection operation on the gradient or Laplacian operators.  Nothing is done with this result here, and I’d like to revisit this later to play with the implications of this factorization in a classical context.