C format programs

S

songbird

I dislike the use of macros which hide
the meaning of the code, but some code I
work on does things like the following and I
don't want to stray too far from the original
version.

I tried both indent, and astyle and neither of
them understand macros enough to know what to do
with things like:


=====
# define when break; case
# define orwhen case
# define otherwise break; default

=====

so the result looks like:

=====

/* Get the options */
while (--argc > 0 && (*++argv)[0] == '-') {
while (*++(*argv)) {
switch (**argv) {
when 'a': full=2;
when 'i': init++;
when 'f': full=1;
when 'm': m = atoi(*argv+1); SKIPARG;
printf ("axe size %d.\n", m);
when 's': seed = atoi(*argv+1); SKIPARG;
printf ("Random seed %d.\n", m);
when 'v': version = atoi(*argv+1); SKIPARG;
printf ("version %d.\n", version);
otherwise: quit (1,
"Usage: axe [-if] [-msv<value>] [axed]\n");
}
}
}

=====

if there is a way to preprocess to expand the macros
without getting all the extra stuff that cpp includes
that could be done.

or if there are any other C code formatters/indenters
that do understand macros I'd be glad to hear of them.


thanks for any ideas,


songbird
 
E

Eric Sosman

[...]
I tried both indent, and astyle and neither of
them understand macros enough to know what to do
with things like:
[... bletcherous code snipped ...]

Ugh. The most fitting punishment would be to force the
author to maintain his own code -- after a five-year hiatus
to let him forget what his "clever" macros did before someone
else "improved" them ...

There's a saying "Thou shalt not use the preprocessor to
violate the syntax," which I think is a little extreme taken
at face value but a good starting point nonetheless. The author
of the code you're facing was apparently inexperienced enough
not to have encountered that adage, or self-important enough to
imagine it didn't apply to him. Too bad.
if there is a way to preprocess to expand the macros
without getting all the extra stuff that cpp includes
that could be done.

or if there are any other C code formatters/indenters
that do understand macros I'd be glad to hear of them.

Question 10.18 in the c.l.c. FAQ <http://www.c-faq.com/>
mentions a few possibilities, although I myself cannot vouch
for them. Good luck! -- you may need it ...
 
S

songbird

Don't make my brown eyes China Blue wrote:
....
If you're using unix, you can expand the macros with something

sed <plugh.c >plugh.ex.c \
's/when/break; case/g' \
's/orwhen/case/g' \
's/otherwise/break; default/g'

Similar tools like perl, tcl, ed are available on a variety of OSes and can also
do this kind of simple string substitution.

yes, of course.

i was thinking of a more general solution for
many other macros... those three are only the
tip of the iceberg.


songbird
 
S

songbird

Eric said:
songbird said:
[...]
I tried both indent, and astyle and neither of
them understand macros enough to know what to do
with things like:
[... bletcherous code snipped ...]

Ugh. The most fitting punishment would be to force the
author to maintain his own code -- after a five-year hiatus
to let him forget what his "clever" macros did before someone
else "improved" them ...

Code written in the early 80s (not by me :) ).
Quite a different age in terms of coding/development
than now. Part of what I'm doing with this project
is learning different tools and ways of doing things
that I didn't have back then.
There's a saying "Thou shalt not use the preprocessor to
violate the syntax," which I think is a little extreme taken
at face value but a good starting point nonetheless. The author
of the code you're facing was apparently inexperienced enough
not to have encountered that adage, or self-important enough to
imagine it didn't apply to him. Too bad.

:)

Well, for sure it isn't something I do. I'd
rather be able to see without having to hunt down
the definition as it may be different than what
I'd expect.

If it is code I'm working on a lot I turn the
macros into function calls as much as possible
and do the text substitutions. But that makes
it hard to do comparisons to the originals to
see what of substance has changed...

Question 10.18 in the c.l.c. FAQ <http://www.c-faq.com/>
mentions a few possibilities, although I myself cannot vouch
for them. Good luck! -- you may need it ...

It's not looking good at the moment, but I'll keep nosing
around, thanks.


songbird
 
I

Ian Collins

If it is code I'm working on a lot I turn the
macros into function calls as much as possible
and do the text substitutions. But that makes
it hard to do comparisons to the originals to
see what of substance has changed...

Use your source control system.

Check in cosmetic changes on their own, never mix them with logic
changes. Then you should be able to isolate the former from the latter
quite easily.
 
K

Keith Thompson

Don't make my brown eyes China Blue said:
If you're using unix, you can expand the macros with something

sed <plugh.c >plugh.ex.c \
's/when/break; case/g' \
's/orwhen/case/g' \
's/otherwise/break; default/g'

Similar tools like perl, tcl, ed are available on a variety of OSes
and can also do this kind of simple string substitution.

Be sure to match `when`, `orwhen`, and `otherwise` as full words. For
sed:

s/\<when\>/break; case/g

et al.

Avoiding substitutions within string literals and comments is left
as an exercise (i.e., I'm too lazy to figure out how to do it).
 
K

Keith Thompson

Ian Collins said:
Use your source control system.

Check in cosmetic changes on their own, never mix them with logic
changes. Then you should be able to isolate the former from the latter
quite easily.

Yes, that's definitely a good idea. But comparison can still be
difficult in some cases.

For example, suppose version 5 is very old, version 10 removes the
ugly macros (so the only difference between versions 9 and 10 is
the cleanup), and version 15 is the current version. If you need
to compare versions 5 and 15, or even 8 and 11, you're still going
to see a mixture of functional changes and cleanup changes.

If you can completely automate the process of fixing the macros,
in a way that works correctly even for older versions, you can
compare a converted copy of version 5 against version 15.

On the other hand, if versions of the code prior to version 9 are
uninteresting, it's probably not worth the effort; automating the
cleanup is likely to be worthwhile anyway, but don't worry about
automating 100% of it vs. 95%.
 
I

ImpalerCore

Don't make my brown eyes China Blue wrote:
...




  yes, of course.

  i was thinking of a more general solution for
many other macros...  those three are only the
tip of the iceberg.

There are a couple of approaches that I can think of, both of which
involve sed or some other text processing scripting language of
choice. Since I'm the most familiar with sed, here are the couple of
approaches that I would suggest.

1. sed solution - Build a lookup table in the hold space when one
runs into a single line '#define' construct. Then for each line that
doesn't contain a #define, paste the hold space contents into the
pattern space and perform a lookup table substitution regex. Not for
the faint of heart.

http://sed.sourceforge.net/grabbag/tutorials/lookup_tables.txt

2. sed + cpp solution - Create a special character sequence to
"comment out" preprocessor directives that you don't want cpp to
preprocess. For example, one can replace the '#' character in front
of every non '#define' statement with some kind of escape sequence.
For example, one can use an autoconf like quadrigraph '# --> @%:mad:'.

@%:mad:include <stdio.h> (cpp will now ignore)

@%:mad:ifdef HAVE_STDINT_H
@%:mad: include <stdint.h>
@%:mad:endif

To preserve comments, one can define another "quadrigraph" sequence to
preserve comments, perhaps '@|:mad: for '//' and '@<:mad:' for '/*' and
'@:>@' for '*/' (probably don't need to do it for '*/'). There may be
other character sequences I'm missing.

Then you pass the source through your 'cpp' preprocessor to perform
the macro substitution, and then filter the results to reestablish the
original preprocessor commands in the #define preprocessed file by
replacing your "quadrigraphs" with your original character sequences.

I recommend something along the lines of option 2, as it seems a bit
easier than the straight up 'sed' route.

Best regards,
John D.
 
J

Joe Pfeiffer

Ian Collins said:
Use your source control system.

Check in cosmetic changes on their own, never mix them with logic
changes. Then you should be able to isolate the former from the
latter quite easily.

If you can cleanly separate your cosmetic changes from your logic
changes when working on code, to the point you can make a bunch of
changes that *only* fit one of those categories at a time, my hat is off
to you as a disciplined programmer.
 
I

Ian Collins

If you can cleanly separate your cosmetic changes from your logic
changes when working on code, to the point you can make a bunch of
changes that *only* fit one of those categories at a time, my hat is off
to you as a disciplined programmer.

Well that depends how often you commit. In my case it's every few
minutes. I always have a never mix the two rule for my teams.
 
S

songbird

Keith said:
Yes, that's definitely a good idea. But comparison can still be
difficult in some cases.

Yes, it's too noisy to be helpful. I'm going to
have to step all the way back to the initial check-in
and then do the formatting there before going forwards
again with the changes.

For example, suppose version 5 is very old, version 10 removes the
ugly macros (so the only difference between versions 9 and 10 is
the cleanup), and version 15 is the current version. If you need
to compare versions 5 and 15, or even 8 and 11, you're still going
to see a mixture of functional changes and cleanup changes.

If you can completely automate the process of fixing the macros,
in a way that works correctly even for older versions, you can
compare a converted copy of version 5 against version 15.

On the other hand, if versions of the code prior to version 9 are
uninteresting, it's probably not worth the effort; automating the
cleanup is likely to be worthwhile anyway, but don't worry about
automating 100% of it vs. 95%.

I have it set up fairly automatic right now
and it almost works exactly as i'd like.


songbird
 
S

songbird

ImpalerCore wrote:
....
There are a couple of approaches that I can think of, both of which
involve sed or some other text processing scripting language of
choice. Since I'm the most familiar with sed, here are the couple of
approaches that I would suggest.

1. sed solution - Build a lookup table in the hold space when one
runs into a single line '#define' construct. Then for each line that
doesn't contain a #define, paste the hold space contents into the
pattern space and perform a lookup table substitution regex. Not for
the faint of heart.

http://sed.sourceforge.net/grabbag/tutorials/lookup_tables.txt

2. sed + cpp solution - Create a special character sequence to
"comment out" preprocessor directives that you don't want cpp to
preprocess. For example, one can replace the '#' character in front
of every non '#define' statement with some kind of escape sequence.
For example, one can use an autoconf like quadrigraph '# --> @%:mad:'.

@%:mad:include <stdio.h> (cpp will now ignore)

@%:mad:ifdef HAVE_STDINT_H
@%:mad: include <stdint.h>
@%:mad:endif

To preserve comments, one can define another "quadrigraph" sequence to
preserve comments, perhaps '@|:mad: for '//' and '@<:mad:' for '/*' and
'@:>@' for '*/' (probably don't need to do it for '*/'). There may be
other character sequences I'm missing.

Then you pass the source through your 'cpp' preprocessor to perform
the macro substitution, and then filter the results to reestablish the
original preprocessor commands in the #define preprocessed file by
replacing your "quadrigraphs" with your original character sequences.

I recommend something along the lines of option 2, as it seems a bit
easier than the straight up 'sed' route.

Best regards,
John D.

Thanks for your reply, :)

Looks quite possible, but I'll wait for a bit
and see if anyone else knows of a tool that will
work.

I'm trying a few others out and we'll see how
they go. Gotta take a break for a few days and
then I'll come back to it and see what has come up.

Thanks everyone,


songbird
 
I

ImpalerCore

ImpalerCore wrote:

...

















  Thanks for your reply,  :)

  Looks quite possible, but I'll wait for a bit
and see if anyone else knows of a tool that will
work.

  I'm trying a few others out and we'll see how
they go.  Gotta take a break for a few days and
then I'll come back to it and see what has come up.

If you are able to post an full example file that you want to process
using pastebin or a direct copy, I'd be willing to take a shot at it
this weekend. If you're not familiar with 'sed', it's a great tool to
learn for tasks like these. The issue is that most sed scripts of
this nature require quite a bit of tweaking to get robust enough to
work, and 'sed' is not the easiest scripting language to wrap your
head around once you want to do more than simple regex substitutions.

Best regards,
John D.
 
J

Joe Pfeiffer

Ian Collins said:
Well that depends how often you commit. In my case it's every few
minutes. I always have a never mix the two rule for my teams.

Ah, you commit far more frequently than I do. I typically keep beating
on a single checkout until a bunch of changes is all in and working (so
several days), or until I want to move the work I'm doing from my
workstation to my laptop or vice versa.
 
S

songbird

ImpalerCore wrote:
....
If you are able to post an full example file that you want to process
using pastebin or a direct copy, I'd be willing to take a shot at it
this weekend. If you're not familiar with 'sed', it's a great tool to
learn for tasks like these. The issue is that most sed scripts of
this nature require quite a bit of tweaking to get robust enough to
work, and 'sed' is not the easiest scripting language to wrap your
head around once you want to do more than simple regex substitutions.

Thanks. Not needed now...

I'm familiar with sed/awk so that isn't a problem.

Several other indenters weren't going to work
any better than astyle (which i'd already applied).

I ended up compromising and only fixing the
few things that were confusing astyle. Leaving
the rest of the macros alone for the moment.
It took about 2hrs to review the code looking
for things that got goobered up but it was only
a few spots. All set, the task is done.


songbird
 
A

Adrian Ratnapala

Well that depends how often you commit. In my case it's every few
Ah, you commit far more frequently than I do. I typically keep beating
on a single checkout until a bunch of changes is all in and working (so
several days), or until I want to move the work I'm doing from my
workstation to my laptop or vice versa.

!!!

(Anyone know a good newsgroup for flame wors about version control
systems?)
 
A

Adrian Ratnapala

Yes, it's too noisy to be helpful. I'm going to
have to step all the way back to the initial check-in
and then do the formatting there before going forwards
again with the changes.

Ouch. The nasty thing is that the hardest merges tend to be where
cosmetic changes have been made on one of the branches. You get
conflicts everywhere, because of small one-character changes.

(But from the rest of the post, it seems like you only want look at the
old revisions. That should be fine, not re-merge the costmetic
changes).
 
P

Phil Carmody

Joe Pfeiffer said:
If you can cleanly separate your cosmetic changes from your logic
changes when working on code, to the point you can make a bunch of
changes that *only* fit one of those categories at a time, my hat is off
to you as a disciplined programmer.

As tree maintainer, I'd just Nack anything that didn't satisfy
Ian's advice. Nobody liked doing their patchset 3 times, they
eventually learn. ``git add -p'' is invaluable.

Phil, the guy who reached [PATCH v7]...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top