为了测试PostScript文件的完整性,我想以下列方式运行Ghostscript:
我可以在后台运行 func updateChartData() {
let chart = PieChartView(frame: self.view.frame)
// 2. generate chart data entries
let track = ["Income", "Expense", "Wallet", "Bank"]
let money = [650, 456.13, 78.67, 856.52]
var entries = [PieChartDataEntry]()
for (index, value) in money.enumerated() {
let entry = PieChartDataEntry()
entry.y = value
entry.label = track[index]
entries.append( entry)
}
// 3. chart setup
let set = PieChartDataSet( values: entries, label: "Pie Chart")
// this is custom extension method. Download the code for more details.
var colors: [UIColor] = []
for _ in 0..<money.count {
let red = Double(arc4random_uniform(256))
let green = Double(arc4random_uniform(256))
let blue = Double(arc4random_uniform(256))
let color = UIColor(red: CGFloat(red/255), green: CGFloat(green/255), blue: CGFloat(blue/255), alpha: 1)
colors.append(color)
}
set.colors = colors
let data = PieChartData(dataSet: set)
chart.data = data
chart.noDataText = "No data available"
// user interaction
chart.isUserInteractionEnabled = true
let d = Description()
d.text = "iOSCharts.io"
chart.chartDescription = d
chart.centerText = "Pie Chart"
chart.holeRadiusPercent = 0.2
chart.transparentCircleColor = UIColor.clear
self.view.addSubview(chart)
}
,如果gs
与堆栈中剩余的项目挂起,则使用超时强制终止。有更简单的解决方案吗?
答案 0 :(得分:1)
如果您将文件作为输入发送,Ghostscript将不会挂起(除非您编写的程序进入无限循环或无法达到暂停状态)。在任何堆栈上放置项目都不会导致它挂起。
另一方面,如果PostScript程序在操作数堆栈(或字典堆栈上的字典,剪辑堆栈上的剪辑或图形状态堆栈上的gstates)上留下操作数,它将不会出现错误。这是因为这不是错误,并且由于PostScript解释器通常在作业服务器循环中运行,因此它也不是问题。终止作业将控制返回到作业服务器循环,该循环对整个作业进行保存和恢复,从而清除遗留的任何内容。
我建议如果你真的想要这样做,你需要采用相同的方法,你需要编写一个PostScript程序来执行你想要'测试'的PostScript程序,然后检查操作数堆栈(和其他如果需要堆叠)以查看是否有任何遗留物。请注意,您将需要在已停止的上下文中执行测试程序,因为程序过程中的错误显然可能会留下任何东西。
如果我没记错的话,Ghostscript会在干净的退出时返回0,并且对于错误返回小于0的值。您需要在测试框架中使用signalerror,以便在项目结束时留下项目时引发错误。
[编辑]
在命令行上由-s或-d提供给Ghostscript的任何内容都在systemdict中定义,所以如果我们-sInputFileName=/test.pdf
,我们会在systemdict中找到一个键/InputFileName
,其值为字符串内容为(/test.pdf)
。我们可以使用它将文件名传递给我们的程序。
stopped
运算符将可执行数组作为参数,并返回true或false,具体取决于执行数组时是否发生错误(第3版PLRM,第697页)。
因此我们需要运行我们已经给出的文件名中包含的程序,并在“已停止”的上下文中执行。像这样:
{InputFileName run} stopped
{
(Error occurred\n) print flush
%% Potentially check $error for more information.
}{
(program terminated normally\n) print flush
%% Here you could check the various stacks
} ifelse
答案 1 :(得分:0)
根据KenS的答案,以下90%的答案是99%令人满意:
计划checkIntegrity.ps
:
{Script run} stopped
{
(\n===> Integrity test failed: ) print Script print ( has error\n\n) print
handleerror
(ignore this error which only serves to force a return value of 1) /syntaxerror signalerror
}{
% script passed, now check the stack
count dup 0 eq {
pop (\n===> Integrity test passed: ) print Script print ( terminated normally\n\n) print
} {
(\n===> Integrity test failed: ) print Script print ( left ) print
3 string cvs print ( item(s) on stack\n\n) print
Script /syntaxerror signalerror
} ifelse
} ifelse
quit
执行
gs -q -sScript=CodeToBeChecked.ps checkIntegrity.ps ; echo $?
对于最后1%的满意度,我需要替换
(blabla) /syntaxerror signalerror
它强制退出并返回代码1,但是非常冗长,并且会分散handleerror
报告的已检查脚本中的实际错误。因此,欢迎exit(1)
更清洁的方式。