# MakeByteArray # # use strict; use warnings; use Cwd qw(cwd); my $maxCols = 16; my $maxLines = 0; my $ESP = 0; my $DIR = 0; my $ROOT = 0; my $UINT8 = 0; my $file = ""; my $ctrlC = 0; # User induced termination my $lineT = 0; # Linecount induced termination $SIG{INT} = \&CtrlCHandler; $SIG{QUIT} = \&CtrlCHandler; my %DirInfo; # Name and FileSize my $prg = $0; $prg =~ s/^.*[\\\/](.*)/$1/; $prg =~ s/(.*)\..*/$1/; my $VERSION = 1.0; # Extension in this list must be lower case. my %FileType = ( "htm" => "text/html", "html" => "text/html", "gif" => "image/gif", "svg" => "image/svg+xml", "css" => "text/css", "ico" => "image/x-icon", "png" => "image/png", "jpg" => "image/jpeg", "js" => "text/javascript", ); if (!@ARGV) { print < [...]] [-n=##] [-l=##] [-ESP] [-DIR] [-o=outfile] version $VERSION Dumps out the contents of the [file(s)] as a c array. If the file is binary, it emits a hex char-array using the -n and -l settings. If the file is text, it emits as an ascii char-array where each source line is one ascii quoted line. -ESP adds the PROGMEM attribute to the byte array data. -DIR adds a 'directory' at the end of the output, providing a reference to each input file. Most useful for a set of files. -ROOT prefixes each entry in the 'directory' with '/', so "index.htm" becomes -o=outfile Writes the output to outfile. -u overrides the default 'char' array to be 'uint8_t' NOTE that the filename and type info remains 'char'. -n=## sets the byte count for each line, defaults 32. -l=## sets a termination after ## lines have been printed. Example: MakeByteArray -ESP srcpath\\*.* -o=dstpath\\Web_Resources.h EOM exit; } my @files; my $outfile = ""; #printf("ARGS: '%s'\n", join("|", @ARGV)); foreach (@ARGV) { if (/-n=(\d+)/) { $maxCols = $1; } elsif (/-l=(\d+)/) { $maxLines = $1; } elsif (/-o=(.*)/) { $outfile = $1; } elsif (/-ESP/) { $ESP = 1; } elsif (/-ROOT/) { $ROOT = 1; } elsif (/-DIR/) { $DIR = 1; } elsif (/-u/) { $UINT8 = 1; } elsif (-e $_ ) { push @files, $_; } elsif (/[\*\?]/) { my @gFiles = glob($_); foreach (@gFiles) { push @files, $_ if (-e $_); } } else { print "unrecognized command.\n"; exit; } } if (!@files) { print "No files to process.\n"; exit; } my $oldHandle; if ($outfile ne "") { #printf("Open for write '%s'\n", $outfile); open(FO, ">$outfile") || die("Can't write to $outfile"); $oldHandle = select FO; } else { printf("No outfile, emitting to console.\n"); } printf("//\n"); printf("// Command: %s %s\n", $prg, join(" ", @ARGV)); printf("// version: %2.1f\n", $VERSION); printf("// From cwd: %s\n", cwd); printf("// Generated: %s\n", scalar localtime()); printf("// NOTE: Run script in command shell, not PowerShell\n"); printf("//\n"); if ($ESP) { print < '%s'\n", $ext, $FileType{lc($ext)}); printf("\t{ %-20s, %-20s, %24s, %6d },\n", $fn, $title, $ftype, $DirInfo{$file}{'size'}); } printf("\t{ %-20s, %-20s, %24s, %6d }\n", "NULL", "NULL", "NULL", 0); printf("};\n\n"); } if ($outfile) { close FO; select($oldHandle); } print "\nTerminated by operator\n" if ($ctrlC == 1); exit; # #################################### sub Process { my $file = shift; my $title = $file; my $isText = 0; my $prototype; $title =~ s/\./_/g; $isText = 1 if (-T $file); open(FH, "<$file") || die("Can't read $file.\n"); binmode FH if ($isText); my $cols = 0; my $c; my $ascii = ""; my $address = 0; my $lineCount = 0; printf("\n"); printf("// File: %s\n", $file); printf("//\n"); $prototype = sprintf("const %s %s[]%s", ($UINT8) ? "uint8_t" : "char", $title, ($ESP) ? " PROGMEM" : ""); printf("%s = {\n", $prototype); my $size = 0; if ($isText) { while () { my $line = $_; chomp $line; $line =~ s/\t/ /g; $line =~ s/\\"/"/g; $line =~ s/\r//g; $line =~ s/"/\\"/g; printf("\t\"%s\\n\"\n", $line); $size += length($line) + 1; # +1 for the \n line termination. } } else { printf("\t"); while (sysread(FH, $c, 1) && !$ctrlC && !$lineT) { my $b = ord($c); printf("0x%02X,", $b); if ($b >= 0x20 && $b <= 0x7F) { $ascii .= chr($b); } else { $ascii .= "."; } ++$cols; ++$address; $cols %= $maxCols; if ($cols == 0) { #print " // $ascii"; print "\n"; $ascii = ""; $lineCount++; $lineT = 1 if ($maxLines && $lineCount >= $maxLines); if (!$lineT) { printf("\t"); } } $size += 1; } if ($ascii ne "") { print " " x ($maxCols - $cols); } printf("\n"); } printf("}; // %s, %d bytes\n", $title, $size); close FH; $DirInfo{$file}{'reference'} = $title; $DirInfo{$file}{'size'} = $size; return $prototype; } # If the user presses Control-C, signal it. # sub CtrlCHandler { $ctrlC = 1; }