Package: fontforge Version: 20120731.b-5 Severity: wishlist Tags: patch User: reproducible-bui...@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
signature.asc
Description: Digital signature