Page 1 of 2

replacing pointer de-referencing syntax

Posted: Mon Jun 09, 2008 10:12 pm
by Nicholas Jordan
I have a massive code directory in which my C - compiler cannot be used because the source uses the -> pointer notation. My compiler does not like that. I found that the correct or traditional notation is ( * varname).member_name which it will recognize.

I have very little experience writing regexs, would like suggestions and discussion because looking for errors introduced by such changes is beyond the scope of my intent at the moment. That will be a matter of digging through line by line and grasping every ( ? - detail - ? )

Re: replacing pointer de-referencing syntax

Posted: Mon Jun 09, 2008 11:15 pm
by gan
Nicholas Jordan wrote:I have a massive code directory in which my C - compiler cannot be used because the source uses the -> pointer notation. My compiler does not like that. I found that the correct or traditional notation is ( * varname).member_name which it will recognize.

I have very little experience writing regexs, would like suggestions and discussion because looking for errors introduced by such changes is beyond the scope of my intent at the moment. That will be a matter of digging through line by line and grasping every ( ? - detail - ? )
It would be much easier if you could provide some lines as an example and clearly show what part you want to remove/change and what you want it to be changed into. Maybe a before and after example and several lines that is not identical and where the > pointer is used differently.

Just curious....what compiler do you use that doesn't like pointers?

Posted: Wed Jun 11, 2008 6:06 pm
by talleyrand
Super rusty here but I suspect input would be
foo = varname->member_name;
output of
foo = ( * varname).member_name;

Therefore, you are looking for something bounded on the left by whitespace, followed by alphanumeric of unknown length, has a ->, is followed by more alphanumerics and ends with whitespace. Those that are much, much better at regex than I will come in and do this better but my first stab would be

search for: \<([[:token:]]*)->([[:token:]]*[[:space:]])\>
replace with: ( * \1).\2

This assumes POSIX regular expressions and that you are using an appropriate syntax sheet for the language (this allows the token class to work). From the help on reg ex "Any of the characters defined on the Syntax page for the document class, or in the syntax definition file if syntax highlighting is enabled for the document class."

sample

Posted: Fri Jun 20, 2008 9:51 pm
by Nicholas Jordan
Sorry, I have been only getting two bars for a month.

Here is some sample code, did download so this is not the original but recode looks like this:

Code: Select all

cpuInfo->ptrBuffer = NULL;
changes to:

Code: Select all

(*cpuInfo).ptrBuffer = NULL;
which is from what I can tell what the -> is syntactical sugar for.

Posted: Fri Jun 20, 2008 11:01 pm
by Bob Hansen
Note, the replace string is using "_" for a space character

Search for: ^(.*)->
Replace with: \(*\1\)_


Use the following settings:
-----------------------------------------
[X] Regular expression
Replace All
-----------------------------------------
Configure | Preferences | Editor
[X] Use POSIX regular expression syntax
-----------------------------------------

clarifiying questions

Posted: Sun Jun 22, 2008 7:21 pm
by Nicholas Jordan
I will study all the replies, but re:
Bob Hansen wrote:Note, the replace string is using "_" for a space character
I think what I need there is \. or something. The start of line character seems out of place as I posted the sample code to be simple. Often in C the code is written as a context free grammer that does not have to be at the start of line. The sample I pasted was not at start of line.

Also, I do not want to insert spaces, the -> should be replaced directly with a literal dot '.' Then additionally I see the backslash and round brace combination as well as the asteric in the replacement. I have figured out that the backslash 1 backslash combination is one-level-deep "what was previously matched" Also I see the round braces that need to be inserted as being { consumed ? } by the escape char preceeding them. { not the double escape of the string backslash ......

I have to get the book and study it along with all the replies, I am taking this first as it is closest to what I expected and is almost readable for me.

I am helping a lot of people right now so it may be awhile before 'marked as solved' Tallyrand is not so rusty, skipping the word boundary we have that the opening and closing round brace is picked up in the match - I think - then there is the [:token:] ~ a c token is definitely what is being sought, and as well the sought token will be an identifier. The double square bracket is news to me. Everything after the replacement of -> with '.' is not needful to pick up, .... the search replace ends with replacement of -> with the dot operator. Spaces do not matter, at least in the resultant. I tend to take them out when recoding anyway so it is C/C++ tokens that we are interested in.

We seek to replace an arbitrary C++ statement of variable_name->member_name with (*variable_name).member_name

variable_name normally being a class or traditional complex data structure.

Gan, it is Digital Mars. The compiler author has written a language called 'D' as a replacement for 'C' and is an Ace and a half. Several things like this have not been fixed to encourage others to migrate to 'D' ~ it has features like built-in foreach construction in the compiler where typing and so on are a routine matter of study and thus may be more effectively implemented.

I just stuck with C because of saturation.

Posted: Sun Jun 22, 2008 11:19 pm
by Bob Hansen
Sorry about the "space" in my earlier sample. I did not see the period on my screen, looked like a space.

Try tp replace ".*" in the Search to the variable value and replace the space with "\."

Search for: (variable_name)->(member_name)
Replace with: \(*\1\)\.\2


The (....) in the Search are to enclose segments that are referenced in the replacement as \1, \2, \3, etc, in sequence.
The "\" is for some special characters to be made literal ( the parentheses and the period).

Explanation of Search:
(variable_name) will become \1 in the replacement
-> are literal characters in the middle
(member_name) will become \2 in the replacement

Explanation of Replace:
\( is for the "("
\1 is for variable_name
\) is for the ")"
\. is for the period
\2 is for member_name

First show of work

Posted: Mon Jun 23, 2008 1:38 am
by Nicholas Jordan
Where you post:

Code: Select all

Search for: (variable_name)->(member_name)
The round braces are not present in the original code.

I do believe you are telling me the \( is to escape the (, which is not in the original but is in the replacement. I do not understand the asterick in Replace with: \(*\1\)\.\2

To show some effort I am guessing the regex would look like:

Code: Select all

Find: \b[a-zA-Z_\d]++(?->))
Replace: \(*\1\)\.
In this code I make backreference \2 go away,... I think. First I had it without the question mark, then I put it in thinking find but do not pick up. Further thinking that by making it \2 I could replace it with the dot, having been found but not used.

Additionally I backslashed the round braces I wanted in the final and put the asterick in because I want a literal asterick prepended to what I placed in the first level of nesting. I could not guess whether it would be escaped in a Replacement pattern.

Then I used word boundary to start the matching followed by a-z upper and lower with underscore and digits greedy. The second level of nesting of round braces in the find, along with the the question mark, is to find but do not pick up -> in the original.

Then I quit writing the regex because everything after the -> in the original is better left untouched on the 'if it is not broken, do not fix it' rule.

After feedback on this, I will make some sample runs. It is routine and expected in my habituated patterns to do preliminary work on copies far removed from what I intend to actually work on. I see now in previewing the post that my replace looks like yours except that \2 is not used. That is done to drop the -> in the original.

Possibly

Code: Select all

Find: \b[a-zA-Z_\d]++(->))
Replace: \(*\1\)\.
In which the \) is to place the closing round brace in the replacment and the \. is to drop special on the dot and just put it literally in the replacement.

Posted: Mon Jun 23, 2008 5:05 am
by Bob Hansen
Did you try the Search and Replace strings that I provided, replacing variable_name and member_name as needed? If not working, what happens, what is the result? It works in every trial for me.

Check out the TextPad Help section for Regular Expressions and Replacement Expressions.

The "rounded braces" are sets of parentheses. They enclose strings to be used in the Replace strings as Tagged Expressions. The second set of (value) will be referenced as \2, the first set of (value) will be referenced as \1.
The Tags \1, \2, etc. are assigned in sequential order of their usage from \1 to \9.
The Tag \0 is also available, that represents the entire Search Pattern.

made some preliminary attempts

Posted: Mon Jun 23, 2008 9:41 pm
by Nicholas Jordan
// Search for: \<(.*)->
// Replace with: \(*\1\)\.

Code: Select all

  key->n = BN_bin2bn(n, sizeof(n)-1, key->n); \
  key->e = BN_bin2bn(e, sizeof(e)-1, key->e); \
  key->d = BN_bin2bn(d, sizeof(d)-1, key->d); \
// Result:

Code: Select all

  (*key->n = BN_bin2bn(n, sizeof(n)-1, key).n); \
  (*key->e = BN_bin2bn(e, sizeof(e)-1, key).e); \
  (*key->d = BN_bin2bn(d, sizeof(d)-1, key).d); \
// Desired:

Code: Select all

  (*key).n = BN_bin2bn(n, sizeof(n)-1, (*key).n); \
  (*key).e = BN_bin2bn(e, sizeof(e)-1, (*key).e); \
  (*key).d = BN_bin2bn(d, sizeof(d)-1, (*key).d); \
// find (\<[a-zA-Z_0-9]+)(?->)
// replace \(*\1\)\.

Code: Select all

#define SetKey \
  key->n = BN_bin2bn(n, sizeof(n)-1, key->n); \
  key->e = BN_bin2bn(e, sizeof(e)-1, key->e); \
  key->d = BN_bin2bn(d, sizeof(d)-1, key->d); \
Result:

Code: Select all

#define SetKey \
  (*key)).n = BN_bin2bn(n, sizeof(n)-1, (*key)).n); \
  (*key)).e = BN_bin2bn(e, sizeof(e)-1, (*key)).e); \
  (*key)).d = BN_bin2bn(d, sizeof(d)-1, (*key)).d); \

The last one is getting close except for the doubled final round brace. Backslashes at end of line are in original. Note that the work is picking up the match near the end, which I had missed visually. I thought backref's worked on nested paren level ~ iow ((()()())))((()() behaves like tree traversal: At any point the depth in the tree is a consequence of simple stack of braces encountered with right hand brace being equivilent to a popStack() and left brace being pushStack(). ()()()()() mapping to \1\2\3\4\5 is what I read you telling me. I made a adhesive note to bring in the actual sources I am intending to work on, the above sample is from performance enhancements to Open SSL

I can also write this as a Java Regular Expression if that would gain us anything.

Posted: Tue Jun 24, 2008 1:30 am
by Bob Hansen
The solution I provided was based on this spec:
We seek to replace an arbitrary C++ statement of variable_name->member_name with (*variable_name).member_name
It will not work correctly on what you have now provided as samples.
Your new spec is more like:
We seek to replace an arbitrary C++ statement of variable_name->otherstuff = otherstuff.member_name

If the format is consistently as you show it now, this should not be a problem, but no time to work on it now.....

Posted: Tue Jun 24, 2008 3:03 pm
by talleyrand
ben_josephs must be off on holiday, he eats these things up. But I believe I've read enough of his replies to know that A) the recognizer used in TP is rather old and limited. B) something about backrefs are part of that old and limited thing.

Not to fear however, the fine WildEdit product uses the modern and more powerfull Boost regex library so it might do what you're looking for. At the very least, I'd expect if you can write the regex in Java then it'd work in WildEdit.

[edit]
Also, my slightly updated regex is
search for: \<([[:token:]]*)->([[:token:]]*)\>
replace with: (*\1).\2

For the samples supplied and using the cpp.syn file for my class, it transformed

Code: Select all

key->n = BN_bin2bn(n, sizeof(n)-1, key->n); \ 
  key->e = BN_bin2bn(e, sizeof(e)-1, key->e); \ 
  key->d = BN_bin2bn(d, sizeof(d)-1, key->d); \
into

Code: Select all

(*key).n = BN_bin2bn(n, sizeof(n)-1, (*key).n); \ 
  (*key).e = BN_bin2bn(e, sizeof(e)-1, (*key).e); \ 
  (*key).d = BN_bin2bn(d, sizeof(d)-1, (*key).d); \
Is there something I'm missing?
[/edit]

rework #2

Posted: Tue Jun 24, 2008 6:32 pm
by Nicholas Jordan
Sorry for the nomenclature bust. I tried full tilt boogie, the nomenclature I used is that I see in professional descriptions.

An identifier, not otherwise a C token often called a variable name in discussions, member_name being an identifier in a struct. Variable name,... oh well the O'Reilly title on Regexs has to go to an exquisite font system to disambiguate.

Talleyrand, I wanted to avoid yet another download and install. My cascading drop-down Start menu is already at 180kb Favorites is 37kb and I am considering writing some sort of cataloging system just to keep up with all the hotlinks. I cheated slightly thinking I would write this as a Java tool, but try to get the Search/Replace tool to do it first. I will gladly share the sources for this is Java if anyone wants them. Gladly.

First off, I brought an exact sample. The actual sources. These are used under § 2 ¶ C clause ii noncommercial and research purposes. of the eula. Second I see that my nomenclature above is not my only blunder. Third, this is a very involved effort so I should probably begin by writing a checker that just pulls to an intermediate file what is found and shows the result of the replacement. The effort is to achieve compilation of Intel® IPP in Java. That could be a remarkable tool for those who wish to do fancy stuff on the web. This is the actual calls into the OS grapical routines from Java sources with the intent of remarkable expansion of pixel depth and is a real workhorse challenge.

Again, if I get this working ~ I will gladly share it with all at TP.

Code: Select all

pMean = jpMean ? (*env)->GetShortArrayElements( env, jpMean, 0 ) : 0;
   mSrcDst = (jdouble **)malloc( jlenmSrcDst * sizeof( jdouble *));
   jobjmSrcDst = (jobject *)malloc( jlenmSrcDst * sizeof( jobject ));
   if ( jmSrcDst ) {
     for (st = 0; st < jlenmSrcDst; st++) {
       jobjmSrcDst[st] = (*env)->GetObjectArrayElement( env, jmSrcDst, st );
       mSrcDst[st] = (*env)->GetDoubleArrayElements( env, jobjmSrcDst[st], 0 );
     }
Using:

Code: Select all

\<([[:token:]]*)->([[:token:]]*)\>
I get cannot find regular expression.

tallyrandFor the samples supplied and using the cpp.syn file for my class
I was not aware of cpp.syn affecting F-8. Set the syn to that on the temp file and used above regex. Got "cannot find".

tallyrandIs there something I'm missing
Your resultant effect is what I intend to achieve, though we now have the dereferencing of the environment pointer to deal with. I have never achieved elementary proficiency on pointer-to-a-pointer practices and so do not know how to couch the question, iow do not know what to ask so I will just put up the results of my work over the last few minutes.

My compiler has an ECMA compliant regex tool as a pre-built class in the libs that can be declared in a C/C++ program. It is probably a reference grade implementation. I tried to study Regex's generally to get this to run, but am slogging in NFA's and compiler science.

Bob, make sure you attend to commitments b4 this ~ but rest assured I tried to do professional grade problem description.

Posted: Wed Jun 25, 2008 1:07 am
by talleyrand
Well, where the syntax file and F8 will come into play is through the use of the [:token:] class. At least, my reading of the help file leads me to that assumption. "Any of the characters defined on the Syntax page for the document class, or in the syntax definition file if syntax highlighting is enabled for the document class." So, whatever we want to call it, my thinking was that the token regular expression class would help at least identify the basic building blocks in the language.

Oh and it looks like that code may be in the wild so no need to do all the legal disclaimers. http://www.google.com/codesearch?hl=en& ... btn=Search

I gotta get a monkey into bed but I'll look at this code and see what I can recall.

Posted: Wed Jun 25, 2008 2:15 pm
by Bob Hansen
This works for me: (Using "_" for space characters in strings)

Search for: __(.*)->(.*,.*,_)(.*)->(.*)
Replace with: \(*\1\)\.\2\(*\3\)\.\4

to get this:
Code:
__key->n = BN_bin2bn(n, sizeof(n)-1, key->n); \
__key->e = BN_bin2bn(e, sizeof(e)-1, key->e); \
__key->d = BN_bin2bn(d, sizeof(d)-1, key->d); \


// Desired:
Code:
__(*key).n = BN_bin2bn(n, sizeof(n)-1, (*key).n); \
__(*key).e = BN_bin2bn(e, sizeof(e)-1, (*key).e); \
__(*key).d = BN_bin2bn(d, sizeof(d)-1, (*key).d); \