#!/usr/bin/env python # -*- Mode: python -*- ## Copyright (C) 2001-2021 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or # implied. # # This software is distributed under license and may not be copied, # modified or distributed except as expressly authorized under the terms # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact # Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, # CA 94945, U.S.A., +1(415)492-9861, for further information. # # update_specific [ | -r ] # # pass files to update via stdin in the following format: # (N|P) # N for normal regression test, P for pdfwrite regression test # must not include a path and must be a file in the # comparefiles directory import os import sys import string import time import tempfile import anydbm import re from popen2 import Popen4 import gstestgs import gsconf import gssum import gsparamsets import rasterdb def norm_entry(cmd, ifile, device, dpi, band, datespec): ofile = "%s.%s.%d.%d" % (ifile, device, dpi, band) print "updating entry: " + ofile + "...", sys.stdout.flush() gs = gstestgs.Ghostscript() gs.command = cmd gs.log_stdout = gsconf.log_stdout gs.log_stderr = gsconf.log_stderr gs.infile = gsconf.comparefiledir + ifile gs.outfile = ofile gs.device = device gs.dpi = dpi gs.band = band if gs.process(): try: if gsconf.log_baseline: log = open(gsconf.log_baseline, "a") log.write(time.ctime() + " " + ifile + " updated "\ "[" + datespec + "]\n") log.close() gssum.add_file(ofile) rasterdb.put_file(ofile) os.unlink(ofile) print "done." except OSError: print "no output produced." else: print "error." def pdf_entry(cmd, ifile, device, dpi, band, datespec): ofile = "%s.pdf.%s.%d.%d" % (ifile, device, dpi, band) print "updating entry: " + ofile + "...", sys.stdout.flush() gs = gstestgs.Ghostscript() gs.log_stdout = gsconf.log_stdout gs.log_stderr = gsconf.log_stderr gs.command = cmd gs.infile = gsconf.comparefiledir + ifile gs.dpi = dpi gs.band = band # make file->PDF tfile = ofile + ".pdf" gs.outfile = tfile gs.device = 'pdfwrite' gs.dpi = None if not gs.process(): print "error." return gs.infile = tfile gs.outfile = ofile gs.device = device gs.dpi = dpi if gs.process(): try: if gsconf.log_baseline: log = open(gsconf.log_baseline, "a") log.write(time.ctime() + " " + ifile + " updated (pdfwrite) "\ "[" + datespec + "]\n") log.close() gssum.add_file(ofile) rasterdb.put_file(ofile) os.unlink(tfile) os.unlink(ofile) print "done." except OSError: print "no output produced." else: print "error." TMP_PREFIX = "REGBUILD." def make_temp_dir(): return tempfile.mkdtemp(prefix=TMP_PREFIX) def kill_temp_dir(dir): if string.find(dir, TMP_PREFIX) == -1: raise StandardError, "Tried to kill a non temp dir!" for root, dirs, files in os.walk(dir, topdown=False): for name in files: os.remove(os.path.join(root, name)) for name in dirs: os.rmdir(os.path.join(root, name)) os.rmdir(dir) def run(cmd, dir): try: os.chdir(dir) pipe = Popen4(cmd) line = pipe.fromchild.readline() while len(line) > 0: sys.stdout.write(line) sys.stdout.flush() line = pipe.fromchild.readline() ret = pipe.wait() except OSError, e: print "ERROR: An exception occured:", e ret = -1 return ret def change_gsproduct(file): tmpfile = "%s.tmp" % (file,) startre = re.compile("^#ifndef\ GS_PRODUCT$") changere = re.compile("^.*?\"[A-Za-z -]+\".*?$") endre = re.compile("^$") old = open(file, "r") new = open(tmpfile, "w") state = 0 for line in old.readlines(): if state == 0: m = startre.search(line) if m: state = 1 new.write(line) elif state == 1: m = changere.search(line) if m: state = 2 new.write("\t\"GPL Ghostscript\"\n") else: new.write(line) elif state == 2: m = endre.search(line) if m: state = 0 new.write(line) old.close() new.close() os.unlink(file) os.rename(tmpfile, file) if len(sys.argv) < 2: print "Not enough arguments." print "usage: update_specific [ -r | ]" print sys.exit(1) if sys.argv[1] == '-r': revspec = sys.argv[2] else: revspec = "{\"" + sys.argv[1] + "\"}" normset = [] pdfset = [] for line in sys.stdin.readlines(): line = string.strip(line) if line[0] == 'N' and line[1] == ' ': normset.append(string.replace(line[2:], '"', '')) elif line[0] == 'P' and line[1] == ' ': pdfset.append(string.replace(line[2:], '"', '')) else: print "Wrong format of arguments given:", line sys.exit(1) print "normal:", normset print "pdf:", pdfset # create the build/install directories and subdirectories tmpdir = make_temp_dir() svndir = os.path.join(tmpdir, "svn") instdir = os.path.join(tmpdir, "inst") builddir = os.path.join(svndir, "gs") os.mkdir(svndir) os.mkdir(instdir) try: # do the svn checkout ret = run("svn checkout -r " + revspec + " " + gsconf.repository + "/trunk/gs", svndir) if ret != 0: raise StandardError, "ERROR: SVN checkout failed" # now configure and build Ghostscript ret = run("./autogen.sh --prefix=" + instdir, builddir) if ret != 0: raise StandardError, "ERROR: configure failed" os.chdir(builddir) change_gsproduct(os.path.join(builddir, "src/gscdef.c")) ret = run("make", builddir) if ret != 0: raise StandardError, "ERROR: make failed" ret = run("make install", builddir) if ret != 0: raise StandardError, "ERROR: make install failed" # install fonts fontdir = os.path.join(instdir, "share", "ghostscript", "fonts") os.mkdir(fontdir) ret = run("cp " + gsconf.fontdir + "* " + fontdir, instdir) if ret != 0: raise StandardError, "ERROR: font installation failed" # update baselines os.chdir(tmpdir) gscmd = os.path.join(instdir, "bin", "gs") for f in normset: for params in gsparamsets.testparamsets: norm_entry(gscmd, f, params.device, params.resolution, params.banding, revspec) for f in pdfset: for params in gsparamsets.pdftestparamsets: pdf_entry(gscmd, f, params.device, params.resolution, params.banding, revspec) except StandardError, e: print "ERROR:", e # clean up our mess kill_temp_dir(tmpdir)