How can I move C comments from the beginning of the line to the end using Perl?
How can I check the next line while running in the current loop? Also, how can I move C comments to the end of the table row?
I have a file like this:
array_table=
{
/* comment 1*/ (unsigned int a);
/* comment 2*/ (unsigned int b);
/* comment 3*/ (unsigned int c);
/* comment 4*/ (unsigned int d);
}
I intend to move these comments to the end of the line, for example:
array_table=
{
(unsigned int a); /* comment 1*/
(unsigned int b); /* comment 2*/
(unsigned int c); /* comment 3*/
(unsigned int d); /* comment 4*/
}
How can I do this in Perl? Can anyone help me with the Perl code?
a source to share
Something like this should work:
while (<>) {
chomp;
if ($_ =~ m%^(.*)/\*(.*)\*/(.*)$%) {
printf "%s%s/*%s*/%s", $1, $3, $2, $/;
} else {
print $_ . $/;
}
}
Bracketed expressions match any request before a comment, the comment itself, and whatever is left after the comment. Then it printf
rearranges them in the correct order.
a source to share
OK - to echo what I think you are asking, you want to parse the file and look for the form settings
foo= { .... }
and inside the block you want to move comments to the end of the line. There are several ways to do this, the most elegant is usually related to what else you do in the loop. The one that comes to mind is just remembering the fact that the last line contained "=" and used that fact when matching for the "{" at the beginning of the line. Using one of my favorite perl constructs, the range operator in scalar context. So it will give ...
my $last_line_an_assignment = 0;
while (<DATA>)
{
if (($last_line_an_assignment && m!^\s*{!) .. m!^\s*}!)
{
s!(/\*.*?\*/)\s*(.*)$!$2 $1!;
}
print $_;
$last_line_an_assignment = m!=!;
}
__DATA__
/* comment other */ (unsigned int a);
other_assignment=
/* not a table */ 12;
array_table=
{
/* comment 1*/ (unsigned int a);
/* comment 2*/ (unsigned int b);
/* comment 3*/ (unsigned int c);
/* comment 4*/ (unsigned int d);
}
/* comment other */ (unsigned int a);
You can either print the data in another file or update the files in-place using the -i option to perl
local (@ARGV) = ($filename);
local ($^I) = '.bak';
while (<>)
{
# make changes to line AND call print
}
This causes perl to back up $ filename (with a ".bak" extension) and then all print calls in the loop will overwrite the contents if the file - see the "-i" option in the "perlrun" page for more information ".
a source to share
Use Regexp :: Common rather than collapse yourself. For instance.
use Regexp::Common;
while ($_ = <DATA>) {
chomp;
if (s/(^\s*)($RE{comment}{C})//) {
print $1, $_, $2, "\n";
}
else {
print $_, "\n";
}
}
__DATA__
/* comment other */ (unsigned int a);
other_assignment=
/* not a table */ 12;
array_table=
{
/* comment 1*/ (unsigned int a);
/* comment 2*/ (unsigned int b);
/* comment 3*/ (unsigned int c);
/* comment 4*/ (unsigned int d);
}
/* comment other */ (unsigned int a);
a source to share