Contribution to the Perl Power Tools: file2c

[email protected] (Thomas Buchholz) Sat, 05 Feb 2005 21:41:49 +0100
Newsgroups perl.ppt
Message-ID <[email protected]>
--------------000403030403080804050706
Content-Type: text/plain; charset=windows-1252; format=flowed
Content-Transfer-Encoding: 8bit

Hi [email protected],

You may find attached a recently coded version of file2c as my 
contribution to the Perl Power Tools. I would be pleased if the code 
would pass all your tests and you would publish it on your web site. If 
you have questions, don’t hesitate to e-mail me. Please, confirm the 
receipt of this message.

Best regards,

Thomas

--------------000403030403080804050706
Content-Type: text/plain;
 name="file2c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="file2c"

#!/usr/bin/perl -w

#
# $Id: file2c,v 1.0 2005/02/05 21:04:03 tbuch Exp $
#
# Revision 1.0  2005/02/05 21:04:03  tbuch
# Initial revision
#

use strict;
use Getopt::Long;

sub version();
sub usage(;$);

my ($VERSION) = '$Revision: 1.0 $' =~ /([.\d]+)/;

# name this program was invoked by 
(my $progname = $0) =~ s{.*/}{};

# position, after which output has to be wrapped
my $wrap_position = 70;

binmode(STDIN); # switch into binary mode

usage(1) unless
    GetOptions('wrap-position=n' => \$wrap_position,
	       'version'         => sub { version(); },
	       'help'            => sub { usage(); },
	      );
usage(1) if @ARGV > 2;

print $ARGV [0], "\n" if @ARGV > 0;

my $buf;
while (read STDIN, $_, 8192) {
    $buf = (defined $buf) ? $buf . ',' : "";
    $buf .= join(',', unpack('C*', $_));
    while (1) {
        my $pos = index($buf, ',');
	last if $pos < 0;
	$pos = $wrap_position if $wrap_position > $pos;
	last if $pos >= length($buf);
	$pos = rindex($buf, ',', $pos) + 1;
	print substr($buf, 0, $pos), "\n";
	$buf = substr($buf, $pos);
    }
}
print $buf, "\n" unless ! defined $buf || $buf eq '';

print $ARGV [1], "\n" if @ARGV > 1;

sub version() {
    print "$progname (Perl bin utils) $VERSION\n";
    exit 0;
}

sub usage (;$) {
    my $status = @_ ? $_ [0] : 0;

    if ($status == 0) {
        print <<EOF
Usage: $progname [OPTIONS] [--] [string] [string]

Options:
       --wrap-position=NUM:  Position after which output has to be wrapped.
       --version:            Print version number, then exit.
       --help:               Print usage, then exit.
EOF
    } else {
        print STDERR "Try \`$progname --help' for more information\n"
    }
    exit $status;
}

__END__

=pod

=head1 NAME

file2c - convert file to C-source

=head1 SYNOPSIS

file2c [B<OPTIONS>] [B<-->] [I<string>] [I<string>]

=head1 DESCRIPTION

The I<file2c> utility reads a file from the standard input and writes it to
the standard output, converting each byte to its decimal representation
on the fly.

=head2 OPTIONS

I<file2c> accepts the following options:

=over 4

=item --help

Print out a short help message, then exit.

=item --version

Print out its version number, then exit.

=item --wrap-position=NUM

Specifies the position after which output has to be wrapped. Counting starts
with 0.

=back

If at most two additional strings are specified on the command line, they
are used as follows. If the first string is present, it is printed before the
data.  If the second string is present, it is printed after the data.

This program is used to embed binary or other files into C source files,
for instance as a char[].

=head1 EXAMPLE

The command:

    $ date | file2c 'const char date[] = {' ',0};'

will produce:

    const char date[] = {
    83,97,116,32,70,101,98,32,32,53,32,50,49,58,48,52,58,48,51,32,32,32,32,
    32,50,48,48,53,10
    ,0};

=head1 SEE ALSO

hexdump(1) od(1)

=head1 BUGS

I<file2c> has no known bugs.

=head1 AUTHOR

The Perl implementation of I<file2c> was written by Thomas `Teebee' Buchholz,
I<[email protected]>.

=head1 COPYRIGHT and LICENSE

This program is copyright (c) Thomas Buchholz 2005.

This program is free and open software. You may use, modify, distribute
and sell this program (and any modified variants) in any way you wish,
provided you do not restrict others to do the same.

=cut

--------------000403030403080804050706--