Package: fontforge
Version: 20120731.b-5
Severity: wishlist
Tags: patch
User: reproducible-builds@lists.alioth.debian.org
Usertags: toolchain timestamps
Control: block -1 by 774148

Hi!

While working on the “reproducible builds” effort [1], we have noticed
that some font packages could not be built reproducibly because they
were building fonts using modifying fontforge scripts. Because of these
these modifications, fontforge will reset the font modification time to
the current time.

In order to have a deterministic build process for these packages, we
need a way to set the generated font modification time to a
predefined value. The attached patch builds upon the one sent for
#774148 and adds a “SetModificationTime” function to fontforge scripting
language. The modification time can then be set with a construct like:

    SetModificationTime(GetEnv("BUILD_DATE"))

The patch also contains a similar modification for the Python module.

 [1]: https://wiki.debian.org/ReproducibleBuilds

-- 
Lunar                                .''`. 
lu...@debian.org                    : :Ⓐ  :  # apt-get install anarchism
                                    `. `'` 
                                      `-   
From 61613ebc1c96352d1379efae05d913ff61cace0f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Bobbio?= <lu...@debian.org>
Date: Tue, 30 Dec 2014 21:15:57 +0100
Subject: [PATCH] Add SetModificationTime function to scripting languages
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

For font compilation to be deterministic, we need a way to set the font
modification time to a defined value instead of the current time.

We thus add a new function “SetModificationTime” to the scripting language.
It takes a single string argument looking like “2014-12-30 21:18:33”.

We also add the corresponding “setModificationTime” method to the
Python bindings.
---
 fontforge/python.c    | 17 +++++++++++++++++
 fontforge/scripting.c | 17 +++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/fontforge/python.c b/fontforge/python.c
index 26b3076..a688795 100644
--- a/fontforge/python.c
+++ b/fontforge/python.c
@@ -13965,6 +13965,22 @@ return(NULL);
 Py_RETURN_NONE;
 }
 
+static PyObject *PyFFFont_setModificationTime(PyObject *self, PyObject *args) {
+    SplineFont *sf = ((PyFF_Font *) self)->fv->sf;
+    struct tm modification_tm;
+    char *date;
+
+    if ( !PyArg_ParseTuple(args,"s", &date ))
+return( NULL );
+
+    if ( NULL == strptime( date, "%Y-%m-%d %H:%M:%S", &modification_tm ) ) {
+	PyErr_Format(PyExc_EnvironmentError, "Unable to parse the date" );
+return(NULL);
+    }
+    sf->modificationtime = mktime( &modification_tm );
+Py_RETURN_NONE;
+}
+
 static PyObject *PyFFFont_replaceAll(PyObject *self, PyObject *args) {
     FontViewBase *fv = ((PyFF_Font *) self)->fv;
     PyObject *srch, *rpl;
@@ -15524,6 +15540,7 @@ static PyMethodDef PyFF_Font_methods[] = {
     { "removeLookup", PyFFFont_removeLookup, METH_VARARGS, "Removes the named lookup" },
     { "removeLookupSubtable", PyFFFont_removeLookupSubtable, METH_VARARGS, "Removes the named lookup subtable" },
     { "saveNamelist", PyFFFont_saveNamelist, METH_VARARGS, "Saves the namelist of the current font." },
+    { "setModificationTime", PyFFFont_setModificationTime, METH_VARARGS, "Set the recorded modification time." },
     { "replaceAll", PyFFFont_replaceAll, METH_VARARGS, "Searches for a pattern in the font and replaces it with another everywhere it was found" },
     { "find", PyFFFont_find, METH_VARARGS, "Searches for a pattern in the font and returns an iterator which produces glyphs with that pattern" },
     { "glyphs", PyFFFont_glyphs, METH_VARARGS, "Returns an iterator over all glyphs" },
diff --git a/fontforge/scripting.c b/fontforge/scripting.c
index 55eb281..d6956fc 100644
--- a/fontforge/scripting.c
+++ b/fontforge/scripting.c
@@ -26,6 +26,7 @@
  */
 /*			   Yet another interpreter			      */
 
+#define _GNU_SOURCE /* for strptime() */
 #include "fontforge.h"
 #include <gfile.h>
 #include <utype.h>
@@ -1574,6 +1575,21 @@ static void bLoadNamelistDir(Context *c) {
     free(dir);
 }
 
+static void bSetModificationTime(Context *c) {
+    SplineFont *sf = c->curfv->sf;
+    struct tm modification_tm;
+
+    if ( c->a.argc!=2 )
+	ScriptError( c, "Wrong number of arguments");
+    else if ( c->a.vals[1].type!=v_str )
+	ScriptError( c, "Expected string argument" );
+
+    if ( NULL == strptime( c->a.vals[1].u.sval, "%Y-%m-%d %H:%M:%S", &modification_tm ) ) {
+	ScriptError( c, "Unable to parse the date" );
+    }
+    sf->modificationtime = mktime( &modification_tm );
+}
+
 /* **** File menu **** */
 
 static void bQuit(Context *c) {
@@ -8052,6 +8068,7 @@ static struct builtins { char *name; void (*func)(Context *); int nofontok; } bu
     { "LoadPluginDir", bLoadPluginDir, 1 },
     { "LoadNamelist", bLoadNamelist, 1 },
     { "LoadNamelistDir", bLoadNamelistDir, 1 },
+    { "SetModificationTime", bSetModificationTime, 1 },
 /* File menu */
     { "Quit", bQuit, 1 },
     { "FontsInFile", bFontsInFile, 1 },
-- 
1.9.1

Attachment: signature.asc
Description: Digital signature

_______________________________________________
Reproducible-builds mailing list
Reproducible-builds@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/reproducible-builds

Reply via email to