1#!/usr/bin/perl
2
3# Copyright (C) 2011 Morten Welinder <terra@gnome.org>
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License as
7# published by the Free Software Foundation; either version 2 of the
8# License, or (at your option) version 3.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
18# USA
19
20use strict;
21use Getopt::Long;
22use IO::Compress::Gzip qw(gzip $GzipError);
23
24my $myself = $0;
25$myself =~ s|^.*/||;
26
27my $WIDTH = 70;
28my $regfunc = undef;
29my $unregfunc = undef;
30my $regfuncstatic = 0;
31my $regfilefunc = "go_rsm_register_file";
32my $unregfilefunc = "go_rsm_unregister_file";
33my $id_prefix = "";
34my @includes;
35
36&GetOptions("register-function=s" => \$regfunc,
37	    "unregister-function=s" => \$unregfunc,
38	    "register-file-function=s" => \$regfilefunc,
39	    "unregister-file-function=s" => \$unregfilefunc,
40	    "static" => \$regfuncstatic,
41	    "id-prefix=s" => \$id_prefix,
42	    "include=s" => \@includes,
43    ) or die "$0: invalid usage -- inquire within\n";
44
45# -----------------------------------------------------------------------------
46
47print "/* Generated by $myself -- do not edit! */\n\n";
48foreach my $include (@includes) {
49    $include = "\"$include\"" unless $include =~ /^[<""]/;
50    print "#include $include\n";
51}
52
53my $fileno = 0;
54my $reg = "";
55my $unreg = "";
56my $docompress = 0;
57print "static " if $regfuncstatic;
58print "void\n";
59print "$regfunc (void)\n";
60print "{\n";
61foreach my $file (@ARGV) {
62    if ($file eq 'COMPRESS') {
63	$docompress = 1;
64	next;
65    }
66    if ($file eq 'NOCOMPRESS') {
67	$docompress = 0;
68	next;
69    }
70    &embed ($file, $docompress);
71}
72print $reg;
73print "}\n";
74
75if (defined $unregfunc) {
76    print "\n";
77    print "static " if $regfuncstatic;
78    print "void\n";
79    print "$unregfunc (void)\n";
80    print "{\n";
81    print $unreg;
82    print "}\n";
83}
84
85sub embed {
86    my ($file, $docompress) = @_;
87
88    print "  /* Embedded file $file */\n";
89
90    my $data;
91    {
92	local (*FIL);
93	local ($/);
94	$/ = undef;
95	open (*FIL, "<$file") or die "$myself: cannot read $file: $!\n";
96	$data = <FIL>;
97    }
98
99    if ($docompress) {
100	my $zdata;
101	gzip \$data => \$zdata, TIME => 0,
102	    or die "gzip failed: $GzipError\n";
103	$data = $zdata;
104    }
105
106    my $id = "data$fileno";
107    $fileno++;
108
109    &embed_data ($data, $id);
110
111    my $res = "$id_prefix$file";
112    my $len = length ($data);
113    $reg .= "  $regfilefunc (\"$res\", $id, $len);\n";
114    $unreg .= "  $unregfilefunc (\"$res\");\n";
115}
116
117sub embed_data {
118    my ($data,$id) = @_;
119
120    my $len = length ($data);
121    if ($len == 0) {
122	print "  static const char ${id}[] = \"\";\n";
123	return;
124    }
125
126    print "  static const char ${id}[] =\n";
127    my $linelen = 0;
128    my $nohex = 0;
129    foreach my $c (split (//, $data)) {
130	if ($linelen > $WIDTH) {
131	    print "\"\n";
132	    $linelen = 0;
133	}
134	if ($linelen == 0) {
135	    print "    \"";
136	    $linelen += 5;
137	    $nohex = 0;
138	}
139
140	my $thisnohex = $nohex;
141	$nohex = 0;
142
143	my $ci = ord ($c);
144	if ($c eq "\n") {
145	    print "\\n";
146	    $linelen += 2;
147	} elsif ($c eq "\t") {
148	    print "\\t";
149	    $linelen += 2;
150	} elsif ($c eq '"') {
151	    print "\\\"";
152	    $linelen += 2;
153	} elsif ($c eq "\\") {
154	    print "\\\\";
155	    $linelen += 2;
156	} elsif ($ci >= 32 && $ci < 127) {
157	    if ($thisnohex && $c =~ /[a-fA-F0-9]/) {
158		print "\"\"";
159		$linelen += 2;
160	    }
161	    print $c;
162	    $linelen += 1;
163	} else {
164	    printf ("\\x%02x", $ci);
165	    $linelen += 4;
166	    $nohex = 1;
167	}
168    }
169    print "\";\n\n";
170}
171