summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile10
-rw-r--r--Makefile.sources2
-rw-r--r--content/fetchers/about.c84
-rwxr-xr-xutils/svn-testament.pl150
4 files changed, 245 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 2761a0dbb..10e9c8779 100644
--- a/Makefile
+++ b/Makefile
@@ -359,7 +359,7 @@ $(TOOLROOT)/created: $(OBJROOT)/created
$(Q)$(MKDIR) $(TOOLROOT)
$(Q)$(TOUCH) $(TOOLROOT)/created
-CLEANS := clean-target
+CLEANS := clean-target clean-testament
POSTEXES :=
@@ -480,6 +480,10 @@ clean-target:
$(VQ)echo " CLEAN: $(EXETARGET)"
$(Q)$(RM) $(EXETARGET)
+clean-testament:
+ $(VQ)echo " CLEAN: utils/testament.h"
+ $(Q)$(RM) utils/testament.h
+
clean-builddir:
$(VQ)echo " CLEAN: $(OBJROOT)"
$(Q)$(RM) -r $(OBJROOT)
@@ -487,6 +491,10 @@ CLEANS += clean-builddir
all-program: $(EXETARGET) post-exe
+.PHONY: testament
+testament:
+ $(Q)$(PERL) utils/svn-testament.pl $(shell pwd) utils/testament.h
+
post-exe: $(POSTEXES)
.SUFFIXES:
diff --git a/Makefile.sources b/Makefile.sources
index 3b9e11368..6651f4943 100644
--- a/Makefile.sources
+++ b/Makefile.sources
@@ -45,6 +45,8 @@ S_BROWSER := browser.c download.c frames.c history_core.c netsurf.c \
save_complete.c save_text.c selection.c textinput.c
S_BROWSER := $(addprefix desktop/,$(S_BROWSER))
+# The following files depend on the testament
+content/fetchers/about.c: testament
# Some extra rules for building the transliteration table.
ifeq ($(HOST),riscos)
diff --git a/content/fetchers/about.c b/content/fetchers/about.c
index 4d6b13ce0..1f441d485 100644
--- a/content/fetchers/about.c
+++ b/content/fetchers/about.c
@@ -46,6 +46,7 @@
#include "utils/url.h"
#include "utils/utils.h"
#include "utils/ring.h"
+#include "utils/testament.h"
struct fetch_about_context;
@@ -279,6 +280,88 @@ fetch_about_choices_handler_aborted:
return false;
}
+/** Generate the text of an svn testament which represents the current
+ * build-tree status
+ */
+typedef struct { const char *leaf; const char modtype; } modification_t;
+static bool fetch_about_testament_handler(struct fetch_about_context *ctx)
+{
+ static modification_t modifications[] = WT_MODIFICATIONS;
+ char buffer[1024];
+ int code = 200;
+ int slen;
+ int i;
+
+
+ /* content is going to return ok */
+ fetch_set_http_code(ctx->fetchh, code);
+
+ /* content type */
+ if (fetch_about_send_header(ctx, "Content-Type: text/plain"))
+ goto fetch_about_testament_handler_aborted;
+
+ slen = snprintf(buffer, sizeof buffer,
+ "# Automatically generated by NetSurf build system\n\n");
+
+ if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
+ FETCH_ERROR_NO_ERROR))
+ goto fetch_about_testament_handler_aborted;
+
+ slen = snprintf(buffer, sizeof buffer,
+#if defined(WT_BRANCHISTRUNK)
+ "# This is a *DEVELOPMENT* build from the trunk.\n\n"
+#elif defined(WT_BRANCHISRELEASE)
+ "# This is a release build of NetSurf\n\n"
+#else
+ "# This NetSurf was built from a branch.\n\n"
+#endif
+ );
+
+ if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
+ FETCH_ERROR_NO_ERROR))
+ goto fetch_about_testament_handler_aborted;
+
+
+ slen = snprintf(buffer, sizeof buffer,
+ "Built by %s (%s) from %s at revision %s\n\n",
+ GECOS, USERNAME, WT_BRANCHPATH, WT_REVID);
+
+ if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
+ FETCH_ERROR_NO_ERROR))
+ goto fetch_about_testament_handler_aborted;
+
+ if (WT_MODIFIED > 0) {
+ slen = snprintf(buffer, sizeof buffer,
+ "Working tree has %d modification%s\n\n",
+ WT_MODIFIED, WT_MODIFIED == 1 ? "" : "s");
+ } else {
+ slen = snprintf(buffer, sizeof buffer,
+ "Working tree is not modified.\n");
+ }
+
+ if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
+ FETCH_ERROR_NO_ERROR))
+ goto fetch_about_testament_handler_aborted;
+
+ for (i = 0; i < WT_MODIFIED; ++i) {
+ slen = snprintf(buffer, sizeof buffer,
+ " %c %s\n",
+ modifications[i].modtype,
+ modifications[i].leaf);
+ if (fetch_about_send_callback(FETCH_DATA, ctx, buffer, slen,
+ FETCH_ERROR_NO_ERROR))
+ goto fetch_about_testament_handler_aborted;
+
+ }
+
+ fetch_about_send_callback(FETCH_FINISHED, ctx, 0, 0,
+ FETCH_ERROR_NO_ERROR);
+
+ return true;
+
+fetch_about_testament_handler_aborted:
+ return false;
+}
struct about_handlers {
const char *name;
@@ -290,6 +373,7 @@ struct about_handlers about_handler_list[] = {
{ "licence", fetch_about_licence_handler },
{ "config", fetch_about_config_handler },
{ "Choices", fetch_about_choices_handler },
+ { "testament", fetch_about_testament_handler },
{ "blank", fetch_about_blank_handler } /* The default */
};
diff --git a/utils/svn-testament.pl b/utils/svn-testament.pl
new file mode 100755
index 000000000..35df4af15
--- /dev/null
+++ b/utils/svn-testament.pl
@@ -0,0 +1,150 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+=head1
+
+Generate a testament describing the current SVN status. This gets written
+out in a C form which can be used to construct the NetSurf SVN testament
+file for signon notification.
+
+If there is no SVN in place, the data is invented arbitrarily.
+
+=cut
+
+my $root = shift @ARGV;
+my $targetfile = shift @ARGV;
+
+my %svninfo; # The SVN info output
+
+my $svn_present = 0;
+if ( -d ".svn" ) {
+ $svn_present = 1;
+}
+
+if ( $svn_present ) {
+ foreach my $line (split(/\n/, `cd $root;svn info`)) {
+ my ($key, $value) = split(/: /, $line, 2);
+ $key = lc($key);
+ $key =~ s/\s+//g;
+ $svninfo{$key} = $value;
+ }
+} else {
+ $svninfo{repositoryroot} = "http://nowhere/";
+ $svninfo{url} = "http://nowhere/netsurf/trunk/";
+ $svninfo{revision} = "0";
+}
+
+my %svnstatus; # The SVN status output
+
+if ( $svn_present ) {
+ foreach my $line (split(/\n/, `cd $root; svn status `)) {
+ my $op = substr($line, 0, 1);
+ if ($op eq ' ' && substr($line, 1, 1) ne ' ') { $op = "p"; }
+ my $fn = substr($line, 7);
+ next unless (care_about_file($fn, $op));
+ $svnstatus{$fn} = $op;
+ }
+}
+
+my %userinfo; # The information about the current user
+
+{
+ my $pwdline = `getent passwd $<`;
+ chomp $pwdline;
+ my @pwdinfo = split(/:/, $pwdline);
+ $userinfo{USERNAME} = $pwdinfo[0];
+ my $gecos = $pwdinfo[4];
+ $gecos =~ s/,.+//g;
+ $gecos =~ s/"/'/g;
+ $userinfo{GECOS} = $gecos;
+}
+
+# Spew the testament out
+
+my $testament = "";
+
+$testament .= "#define USERNAME \"$userinfo{USERNAME}\"\n";
+$testament .= "#define GECOS \"$userinfo{GECOS}\"\n";
+
+my $url = $svninfo{url};
+# This only works on 1.3.x and above
+$url = substr($url, length($svninfo{repositoryroot}));
+if ( substr($url,0,1) ne '/' ) { $url = "/$url"; }
+$testament .= "#define WT_BRANCHPATH \"$url\"\n";
+if ($url =~ m@/trunk/@) {
+ $testament .= "#define WT_BRANCHISTRUNK 1\n";
+}
+if ($url =~ m@/tags/@) {
+ $testament .= "#define WT_BRANCHISTAG 1\n";
+}
+$testament .= "#define WT_REVID \"$svninfo{revision}\"\n";
+$testament .= "#define WT_MODIFIED " . scalar(keys %svnstatus) . "\n";
+$testament .= "#define WT_MODIFICATIONS {\\\n";
+my $doneone = 0;
+foreach my $filename (sort keys %svnstatus) {
+ if ($doneone) {
+ $testament .= ", \\\n";
+ }
+ $testament .= " { \"$filename\", '$svnstatus{$filename}' }";
+ $doneone = 1;
+}
+$testament .= " \\\n}\n";
+
+use Digest::MD5 qw(md5_hex);
+
+my $oldcsum = "";
+if ( -e $targetfile ) {
+ open OLDVALUES, "<", $targetfile;
+ foreach my $line (readline(OLDVALUES)) {
+ if ($line =~ /MD5:([0-9a-f]+)/) {
+ $oldcsum = $1;
+ }
+ }
+ close OLDVALUES;
+}
+
+my $newcsum = md5_hex($testament);
+
+if ($oldcsum ne $newcsum) {
+ print "TESTMENT: $targetfile\n";
+ open NEWVALUES, ">", $targetfile or die "$!";
+ print NEWVALUES "/* ", $targetfile,"\n";
+ print NEWVALUES <<'EOS';
+ *
+ * Revision testament.
+ *
+ * *WARNING* this file is automatically generated by svn-testament.pl
+ *
+ * Copyright 2011 NetSurf Browser Project
+ */
+
+EOS
+
+ print NEWVALUES "#ifndef NETSURF_REVISION_TESTAMENT\n";
+ print NEWVALUES "#define NETSURF_REVISION_TESTAMENT \"$newcsum\"\n\n";
+ print NEWVALUES "/* Revision testament checksum:\n";
+ print NEWVALUES " * MD5:", $newcsum,"\n */\n\n";
+ print NEWVALUES "/* Revision testament: */\n";
+ print NEWVALUES $testament;
+ print NEWVALUES "\n#endif\n";
+ close NEWVALUES;
+ foreach my $unwanted (@ARGV) {
+ next unless(-e $unwanted);
+ print "TESTAMENT: Removing $unwanted\n";
+ system("rm", "-f", "--", $unwanted);
+ }
+} else {
+ print "TESTMENT: unchanged\n";
+}
+
+exit 0;
+
+sub care_about_file {
+ my ($fn, $op) = @_;
+ return 0 if ($fn =~ /\.d$/); # Don't care for extraneous DEP files
+ return 0 if ($fn =~ /\.a$/); # Don't care for extraneous archive files
+ return 0 if ($fn =~ /\.md5$/); # Don't care for md5sum files
+ return 0 if ($fn =~ /\.map$/); # Don't care for map files
+ return 1;
+}